Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

extsect.c File Reference

#include "mi.h"

Go to the source code of this file.

Functions

NTSTATUS NtExtendSection (IN HANDLE SectionHandle, IN OUT PLARGE_INTEGER NewSectionSize)
NTSTATUS MmExtendSection (IN PVOID SectionToExtend, IN OUT PLARGE_INTEGER NewSectionSize, IN ULONG IgnoreFileSizeChecking)
PMMPTE FASTCALL MiGetProtoPteAddressExtended (IN PMMVAD Vad, IN ULONG_PTR Vpn)
PSUBSECTION FASTCALL MiLocateSubsection (IN PMMVAD Vad, IN ULONG_PTR Vpn)


Function Documentation

PMMPTE FASTCALL MiGetProtoPteAddressExtended IN PMMVAD  Vad,
IN ULONG_PTR  Vpn
 

Definition at line 685 of file extsect.c.

References ASSERT, _SUBSECTION::NextSubsection, NULL, _SUBSECTION::PtesInSubsection, _SUBSECTION::SubsectionBase, and _CONTROL_AREA::u.

00692 : 00693 00694 This function calculates the address of the prototype PTE 00695 for the corresponding virtual address. 00696 00697 Arguments: 00698 00699 00700 Vad - Supplies a pointer to the virtual address desciptor which 00701 encompasses the virtual address. 00702 00703 Vpn - Supplies the virtual page number to locate a prototype PTE 00704 for. 00705 00706 Return Value: 00707 00708 The corresponding prototype PTE address. 00709 00710 --*/ 00711 00712 { 00713 PSUBSECTION Subsection; 00714 PCONTROL_AREA ControlArea; 00715 ULONG PteOffset; 00716 00717 ControlArea = Vad->ControlArea; 00718 00719 if (ControlArea->u.Flags.GlobalOnlyPerSession == 0) { 00720 Subsection = (PSUBSECTION)(ControlArea + 1); 00721 } 00722 else { 00723 Subsection = (PSUBSECTION)((PLARGE_CONTROL_AREA)ControlArea + 1); 00724 } 00725 00726 // 00727 // Locate the subsection which contains the First Prototype PTE 00728 // for this VAD. 00729 // 00730 00731 while ((Vad->FirstPrototypePte < Subsection->SubsectionBase) || 00732 (Vad->FirstPrototypePte >= 00733 &Subsection->SubsectionBase[Subsection->PtesInSubsection])) { 00734 00735 // 00736 // Get the next subsection. 00737 // 00738 00739 Subsection = Subsection->NextSubsection; 00740 if (Subsection == NULL) { 00741 return NULL; 00742 } 00743 } 00744 00745 // 00746 // How many PTEs beyond this subsection must we go? 00747 // 00748 00749 PteOffset = (ULONG) (((Vpn - Vad->StartingVpn) + 00750 (ULONG)(Vad->FirstPrototypePte - Subsection->SubsectionBase)) - 00751 Subsection->PtesInSubsection); 00752 00753 // DbgPrint("map extended subsection offset = %lx\n",PteOffset); 00754 00755 ASSERT (PteOffset < 0xF0000000); 00756 00757 PteOffset += Subsection->PtesInSubsection; 00758 00759 // 00760 // Locate the subsection which contains the prototype PTEs. 00761 // 00762 00763 while (PteOffset >= Subsection->PtesInSubsection) { 00764 PteOffset -= Subsection->PtesInSubsection; 00765 Subsection = Subsection->NextSubsection; 00766 if (Subsection == NULL) { 00767 return NULL; 00768 } 00769 } 00770 00771 // 00772 // The PTEs are in this subsection. 00773 // 00774 00775 ASSERT (PteOffset < Subsection->PtesInSubsection); 00776 00777 return &Subsection->SubsectionBase[PteOffset]; 00778 00779 }

PSUBSECTION FASTCALL MiLocateSubsection IN PMMVAD  Vad,
IN ULONG_PTR  Vpn
 

Definition at line 783 of file extsect.c.

References ASSERT, _SUBSECTION::NextSubsection, NULL, _SUBSECTION::PtesInSubsection, _SUBSECTION::SubsectionBase, and _CONTROL_AREA::u.

Referenced by MiDeleteVirtualAddresses(), and MmFlushVirtualMemory().

00790 : 00791 00792 This function calculates the address of the subsection 00793 for the corresponding virtual address. 00794 00795 This function only works for mapped files NOT mapped images. 00796 00797 Arguments: 00798 00799 00800 Vad - Supplies a pointer to the virtual address desciptor which 00801 encompasses the virtual address. 00802 00803 Vpn - Supplies the virtual page number to locate a prototype PTE 00804 for. 00805 00806 Return Value: 00807 00808 The corresponding prototype subsection. 00809 00810 --*/ 00811 00812 { 00813 PSUBSECTION Subsection; 00814 PCONTROL_AREA ControlArea; 00815 ULONG PteOffset; 00816 00817 ControlArea = Vad->ControlArea; 00818 00819 if (ControlArea->u.Flags.GlobalOnlyPerSession == 0) { 00820 Subsection = (PSUBSECTION)(ControlArea + 1); 00821 } 00822 else { 00823 Subsection = (PSUBSECTION)((PLARGE_CONTROL_AREA)ControlArea + 1); 00824 } 00825 00826 Subsection = (PSUBSECTION)(ControlArea + 1); 00827 00828 #if 0 00829 if (Subsection->NextSubsection == NULL) { 00830 00831 // 00832 // There is only one subsection, don't look any further. 00833 // 00834 00835 return Subsection; 00836 } 00837 #endif //0 00838 00839 if (ControlArea->u.Flags.Image) { 00840 00841 // 00842 // There is only one subsection, don't look any further. 00843 // 00844 00845 return Subsection; 00846 } 00847 00848 // 00849 // Locate the subsection which contains the First Prototype PTE 00850 // for this VAD. 00851 // 00852 00853 while ((Vad->FirstPrototypePte < Subsection->SubsectionBase) || 00854 (Vad->FirstPrototypePte >= 00855 &Subsection->SubsectionBase[Subsection->PtesInSubsection])) { 00856 00857 // 00858 // Get the next subsection. 00859 // 00860 00861 Subsection = Subsection->NextSubsection; 00862 if (Subsection == NULL) { 00863 return NULL; 00864 } 00865 } 00866 00867 // 00868 // How many PTEs beyond this subsection must we go? 00869 // 00870 00871 PteOffset = (ULONG)((Vpn - Vad->StartingVpn) + 00872 (ULONG)(Vad->FirstPrototypePte - Subsection->SubsectionBase)); 00873 00874 ASSERT (PteOffset < 0xF0000000); 00875 00876 // 00877 // Locate the subsection which contains the prototype PTEs. 00878 // 00879 00880 while (PteOffset >= Subsection->PtesInSubsection) { 00881 PteOffset -= Subsection->PtesInSubsection; 00882 Subsection = Subsection->NextSubsection; 00883 if (Subsection == NULL) { 00884 return NULL; 00885 } 00886 } 00887 00888 // 00889 // The PTEs are in this subsection. 00890 // 00891 00892 return Subsection; 00893 } }

NTSTATUS MmExtendSection IN PVOID  SectionToExtend,
IN OUT PLARGE_INTEGER  NewSectionSize,
IN ULONG  IgnoreFileSizeChecking
 

Definition at line 201 of file extsect.c.

References ASSERT, _MMEXTEND_INFO::CommittedSize, _SUBSECTION::ControlArea, _SEGMENT::ControlArea, DbgPrint, _CONTROL_AREA::DereferenceList, EX_REAL_POOL_USAGE, ExAcquireResourceExclusive, ExAllocatePoolWithTag, ExFreePool(), ExReleaseResource, _SEGMENT::ExtendInfo, FALSE, _CONTROL_AREA::FilePointer, FsRtlGetFileSize(), FsRtlSetFileSize(), KeEnterCriticalRegion, KeLeaveCriticalRegion, Mi4KStartForSubsection, Mi4KStartFromSubsection, MI_GET_PROTECTION_FROM_SOFT_PTE, MI_MAXIMUM_SECTION_SIZE, MI_WRITE_INVALID_PTE, MiGetSubsectionAddressForPte, MM4K_MASK, MM4K_SHIFT, MMPTE, MmSectionBasedMutex, MmSectionExtendResource, MmSectionExtendSetResource, _SUBSECTION::NextSubsection, NonPagedPool, _CONTROL_AREA::NonPagedPoolUsage, NT_SUCCESS, NTSTATUS(), NULL, _SUBSECTION::NumberOfFullSectors, PAGE_SHIFT, PAGE_SIZE, PAGED_CODE, PagedPool, _CONTROL_AREA::PagedPoolUsage, PSECTION, _SUBSECTION::PtesInSubsection, ROUND_TO_PAGES, _CONTROL_AREA::Segment, _SEGMENT::SegmentPteTemplate, _SEGMENT::SizeOfSegment, Status, SUBSECTION, _SUBSECTION::SubsectionBase, _SEGMENT::TotalNumberOfPtes, TRUE, _MMPTE::u, _SUBSECTION::u, _CONTROL_AREA::u, and _SUBSECTION::UnusedPtes.

Referenced by CcInitializeCacheMap(), CcSetFileSizes(), MmCreateSection(), NtAllocateVirtualMemory(), and NtExtendSection().

00209 : 00210 00211 This function extends the size of the specified section. If 00212 the current size of the section is greater than or equal to the 00213 specified section size, the size is not updated. 00214 00215 Arguments: 00216 00217 Section - Supplies a pointer to a referenced section object. 00218 00219 NewSectionSize - Supplies the new size for the section object. 00220 00221 IgnoreFileSizeChecking - Supplies the value TRUE is file size 00222 checking should be ignored (i.e., it 00223 is being called from a file system which 00224 has already done the checks). FALSE 00225 if the checks still need to be made. 00226 00227 Return Value: 00228 00229 Returns the status 00230 00231 TBS 00232 00233 00234 --*/ 00235 00236 { 00237 PMMPTE PointerPte; 00238 PMMPTE LastPte; 00239 PMMPTE ExtendedPtes; 00240 MMPTE TempPte; 00241 PCONTROL_AREA ControlArea; 00242 PSECTION Section; 00243 PSUBSECTION LastSubsection; 00244 PSUBSECTION ExtendedSubsection; 00245 ULONG RequiredPtes; 00246 ULONG NumberOfPtes; 00247 ULONG PtesUsed; 00248 ULONG AllocationSize; 00249 UINT64 EndOfFile; 00250 UINT64 NumberOfPtesForEntireFile; 00251 NTSTATUS Status; 00252 LARGE_INTEGER NumberOf4KsForEntireFile; 00253 LARGE_INTEGER Starting4K; 00254 LARGE_INTEGER Last4KChunk; 00255 00256 PAGED_CODE(); 00257 00258 Section = (PSECTION)SectionToExtend; 00259 00260 // 00261 // Make sure the section is really extendable - physical and 00262 // image sections are not. 00263 // 00264 00265 ControlArea = Section->Segment->ControlArea; 00266 00267 if ((ControlArea->u.Flags.PhysicalMemory || ControlArea->u.Flags.Image) || 00268 (ControlArea->FilePointer == NULL)) { 00269 return STATUS_SECTION_NOT_EXTENDED; 00270 } 00271 00272 // 00273 // Acquire the section extension mutex, this blocks other threads from 00274 // updating the size at the same time. 00275 // 00276 00277 KeEnterCriticalRegion (); 00278 ExAcquireResourceExclusive (&MmSectionExtendResource, TRUE); 00279 00280 // 00281 // Each subsection is limited to 16TB - 64K because the NumberOfFullSectors 00282 // and various other fields in the subsection are ULONGs. For NT64, the 00283 // allocation could be split into multiple subsections as needed to 00284 // conform to this limit - this is not worth doing for NT32 unless 00285 // sparse prototype PTE allocations are supported. 00286 // 00287 00288 // This must be a multiple of the size of prototype pte allocation so any 00289 // given prototype pte allocation will have the same subsection for all 00290 // PTEs. 00291 // 00292 // The total section size is limited to 16PB - 4K because of the 00293 // StartingSector4132 field in each subsection. 00294 // 00295 00296 NumberOfPtesForEntireFile = (NewSectionSize->QuadPart + PAGE_SIZE - 1) >> PAGE_SHIFT; 00297 00298 NumberOfPtes = (ULONG)NumberOfPtesForEntireFile; 00299 00300 if (NewSectionSize->QuadPart > MI_MAXIMUM_SECTION_SIZE) { 00301 Status = STATUS_SECTION_TOO_BIG; 00302 goto ReleaseAndReturn; 00303 } 00304 00305 if (NumberOfPtesForEntireFile > (UINT64)((MAXULONG_PTR / sizeof(MMPTE)) - sizeof (SEGMENT))) { 00306 Status = STATUS_SECTION_TOO_BIG; 00307 goto ReleaseAndReturn; 00308 } 00309 00310 if (NumberOfPtesForEntireFile > (UINT64)NewSectionSize->QuadPart) { 00311 Status = STATUS_SECTION_TOO_BIG; 00312 goto ReleaseAndReturn; 00313 } 00314 00315 if (ControlArea->u.Flags.WasPurged == 0) { 00316 00317 if ((UINT64)NewSectionSize->QuadPart <= (UINT64)Section->SizeOfSection.QuadPart) { 00318 *NewSectionSize = Section->SizeOfSection; 00319 goto ReleaseAndReturnSuccess; 00320 } 00321 } 00322 00323 // 00324 // If a file handle was specified, set the allocation size of the file. 00325 // 00326 00327 if (IgnoreFileSizeChecking == FALSE) { 00328 00329 // 00330 // Release the resource so we don't deadlock with the file 00331 // system trying to extend this section at the same time. 00332 // 00333 00334 ExReleaseResource (&MmSectionExtendResource); 00335 00336 // 00337 // Get a different resource to single thread query/set operations. 00338 // 00339 00340 ExAcquireResourceExclusive (&MmSectionExtendSetResource, TRUE); 00341 00342 // 00343 // Query the file size to see if this file really needs extending. 00344 // 00345 // If the specified size is less than the current size, return 00346 // the current size. 00347 // 00348 00349 Status = FsRtlGetFileSize (ControlArea->FilePointer, 00350 (PLARGE_INTEGER)&EndOfFile); 00351 00352 if (!NT_SUCCESS (Status)) { 00353 ExReleaseResource (&MmSectionExtendSetResource); 00354 KeLeaveCriticalRegion (); 00355 return Status; 00356 } 00357 00358 if ((UINT64)NewSectionSize->QuadPart > EndOfFile) { 00359 00360 // 00361 // Don't allow section extension unless the section was originally 00362 // created with write access. The check couldn't be done at create 00363 // time without breaking existing binaries, so the caller gets the 00364 // error at this point instead. 00365 // 00366 00367 if (((Section->InitialPageProtection & PAGE_READWRITE) | 00368 (Section->InitialPageProtection & PAGE_EXECUTE_READWRITE)) == 0) { 00369 #if DBG 00370 DbgPrint("Section extension failed %x\n", Section); 00371 #endif 00372 ExReleaseResource (&MmSectionExtendSetResource); 00373 KeLeaveCriticalRegion (); 00374 return STATUS_SECTION_NOT_EXTENDED; 00375 } 00376 00377 // 00378 // Current file is smaller, attempt to set a new end of file. 00379 // 00380 00381 EndOfFile = *(PUINT64)NewSectionSize; 00382 00383 Status = FsRtlSetFileSize (ControlArea->FilePointer, 00384 (PLARGE_INTEGER)&EndOfFile); 00385 00386 if (!NT_SUCCESS (Status)) { 00387 ExReleaseResource (&MmSectionExtendSetResource); 00388 KeLeaveCriticalRegion (); 00389 return Status; 00390 } 00391 } 00392 00393 if (ControlArea->Segment->ExtendInfo) { 00394 ExAcquireFastMutex (&MmSectionBasedMutex); 00395 if (ControlArea->Segment->ExtendInfo) { 00396 ControlArea->Segment->ExtendInfo->CommittedSize = EndOfFile; 00397 } 00398 ExReleaseFastMutex (&MmSectionBasedMutex); 00399 } 00400 00401 // 00402 // Release the query/set resource and reacquire the extend section 00403 // resource. 00404 // 00405 00406 ExReleaseResource (&MmSectionExtendSetResource); 00407 ExAcquireResourceExclusive (&MmSectionExtendResource, TRUE); 00408 } 00409 00410 // 00411 // Find the last subsection. 00412 // 00413 00414 ASSERT (ControlArea->u.Flags.GlobalOnlyPerSession == 0); 00415 00416 LastSubsection = (PSUBSECTION)(ControlArea + 1); 00417 00418 while (LastSubsection->NextSubsection != NULL ) { 00419 ASSERT (LastSubsection->UnusedPtes == 0); 00420 LastSubsection = LastSubsection->NextSubsection; 00421 } 00422 00423 #if DBG 00424 MiSubsectionConsistent(LastSubsection); 00425 #endif 00426 00427 // 00428 // Does the structure need extending? 00429 // 00430 00431 if (NumberOfPtes <= Section->Segment->TotalNumberOfPtes) { 00432 00433 // 00434 // The segment is already large enough, just update 00435 // the section size and return. 00436 // 00437 00438 Section->SizeOfSection = *NewSectionSize; 00439 if (Section->Segment->SizeOfSegment < (UINT64)NewSectionSize->QuadPart) { 00440 // 00441 // Only update if it is really bigger. 00442 // 00443 00444 Section->Segment->SizeOfSegment = *(PUINT64)NewSectionSize; 00445 00446 Mi4KStartFromSubsection(&Starting4K, LastSubsection); 00447 00448 Last4KChunk.QuadPart = (NewSectionSize->QuadPart >> MM4K_SHIFT) - Starting4K.QuadPart; 00449 00450 ASSERT (Last4KChunk.HighPart == 0); 00451 00452 LastSubsection->NumberOfFullSectors = Last4KChunk.LowPart; 00453 LastSubsection->u.SubsectionFlags.SectorEndOffset = 00454 NewSectionSize->LowPart & MM4K_MASK; 00455 #if DBG 00456 MiSubsectionConsistent(LastSubsection); 00457 #endif 00458 } 00459 goto ReleaseAndReturnSuccess; 00460 } 00461 00462 // 00463 // Add new structures to the section - locate the last subsection 00464 // and add there. 00465 // 00466 00467 RequiredPtes = NumberOfPtes - Section->Segment->TotalNumberOfPtes; 00468 PtesUsed = 0; 00469 00470 if (RequiredPtes < LastSubsection->UnusedPtes) { 00471 00472 // 00473 // There are ample PTEs to extend the section already allocated. 00474 // 00475 00476 PtesUsed = RequiredPtes; 00477 RequiredPtes = 0; 00478 00479 } else { 00480 PtesUsed = LastSubsection->UnusedPtes; 00481 RequiredPtes -= PtesUsed; 00482 } 00483 00484 LastSubsection->PtesInSubsection += PtesUsed; 00485 LastSubsection->UnusedPtes -= PtesUsed; 00486 ControlArea->Segment->SizeOfSegment += (ULONG_PTR)PtesUsed * PAGE_SIZE; 00487 ControlArea->Segment->TotalNumberOfPtes += PtesUsed; 00488 00489 if (RequiredPtes == 0) { 00490 00491 // 00492 // There is no extension necessary, update the high VBN. 00493 // 00494 00495 Mi4KStartFromSubsection(&Starting4K, LastSubsection); 00496 00497 Last4KChunk.QuadPart = (NewSectionSize->QuadPart >> MM4K_SHIFT) - Starting4K.QuadPart; 00498 00499 ASSERT (Last4KChunk.HighPart == 0); 00500 00501 LastSubsection->NumberOfFullSectors = Last4KChunk.LowPart; 00502 00503 LastSubsection->u.SubsectionFlags.SectorEndOffset = 00504 NewSectionSize->LowPart & MM4K_MASK; 00505 #if DBG 00506 MiSubsectionConsistent(LastSubsection); 00507 #endif 00508 } else { 00509 00510 // 00511 // An extension is required. Allocate paged pool 00512 // and populate it with prototype PTEs. 00513 // 00514 00515 AllocationSize = (ULONG) ROUND_TO_PAGES (RequiredPtes * sizeof(MMPTE)); 00516 00517 ExtendedPtes = (PMMPTE)ExAllocatePoolWithTag (PagedPool, 00518 AllocationSize, 00519 'ppmM'); 00520 00521 if (ExtendedPtes == NULL) { 00522 00523 // 00524 // The required pool could not be allocated. Reset 00525 // the subsection and control area fields to their 00526 // original values. 00527 // 00528 00529 LastSubsection->PtesInSubsection -= PtesUsed; 00530 LastSubsection->UnusedPtes += PtesUsed; 00531 ControlArea->Segment->TotalNumberOfPtes -= PtesUsed; 00532 ControlArea->Segment->SizeOfSegment -= ((ULONG_PTR)PtesUsed * PAGE_SIZE); 00533 Status = STATUS_INSUFFICIENT_RESOURCES; 00534 goto ReleaseAndReturn; 00535 } 00536 00537 // 00538 // Allocate an extended subsection descriptor. 00539 // 00540 00541 ExtendedSubsection = (PSUBSECTION)ExAllocatePoolWithTag (NonPagedPool, 00542 sizeof(SUBSECTION), 00543 'bSmM' 00544 ); 00545 if (ExtendedSubsection == NULL) { 00546 00547 // 00548 // The required pool could not be allocated. Reset 00549 // the subsection and control area fields to their 00550 // original values. 00551 // 00552 00553 LastSubsection->PtesInSubsection -= PtesUsed; 00554 LastSubsection->UnusedPtes += PtesUsed; 00555 ControlArea->Segment->TotalNumberOfPtes -= PtesUsed; 00556 ControlArea->Segment->SizeOfSegment -= ((ULONG_PTR)PtesUsed * PAGE_SIZE); 00557 ExFreePool (ExtendedPtes); 00558 Status = STATUS_INSUFFICIENT_RESOURCES; 00559 goto ReleaseAndReturn; 00560 } 00561 00562 ControlArea->NonPagedPoolUsage += EX_REAL_POOL_USAGE(sizeof(SUBSECTION)); 00563 ControlArea->PagedPoolUsage += AllocationSize; 00564 00565 ASSERT (ControlArea->DereferenceList.Flink == NULL); 00566 00567 NumberOf4KsForEntireFile.QuadPart = 00568 ControlArea->Segment->SizeOfSegment >> MM4K_SHIFT; 00569 00570 Mi4KStartFromSubsection(&Starting4K, LastSubsection); 00571 00572 Last4KChunk.QuadPart = NumberOf4KsForEntireFile.QuadPart - 00573 Starting4K.QuadPart; 00574 00575 if (LastSubsection->u.SubsectionFlags.SectorEndOffset) { 00576 Last4KChunk.QuadPart += 1; 00577 } 00578 00579 ASSERT(Last4KChunk.HighPart == 0); 00580 00581 LastSubsection->NumberOfFullSectors = Last4KChunk.LowPart; 00582 LastSubsection->u.SubsectionFlags.SectorEndOffset = 0; 00583 00584 // 00585 // If the number of sectors doesn't completely fill the PTEs (this can 00586 // only happen when the page size is not MM4K), then fill it now. 00587 // 00588 00589 if (LastSubsection->NumberOfFullSectors & ((1 << (PAGE_SHIFT - MM4K_SHIFT)) - 1)) { 00590 LastSubsection->NumberOfFullSectors += 1; 00591 } 00592 00593 #if DBG 00594 MiSubsectionConsistent(LastSubsection); 00595 #endif 00596 00597 ExtendedSubsection->u.LongFlags = 0; 00598 ExtendedSubsection->NextSubsection = NULL; 00599 ExtendedSubsection->UnusedPtes = (AllocationSize / sizeof(MMPTE)) - 00600 RequiredPtes; 00601 00602 ExtendedSubsection->ControlArea = ControlArea; 00603 ExtendedSubsection->PtesInSubsection = RequiredPtes; 00604 00605 Starting4K.QuadPart += LastSubsection->NumberOfFullSectors; 00606 00607 Mi4KStartForSubsection(&Starting4K, ExtendedSubsection); 00608 00609 Last4KChunk.QuadPart = 00610 (NewSectionSize->QuadPart >> MM4K_SHIFT) - Starting4K.QuadPart; 00611 00612 ASSERT(Last4KChunk.HighPart == 0); 00613 00614 ExtendedSubsection->NumberOfFullSectors = Last4KChunk.LowPart; 00615 ExtendedSubsection->u.SubsectionFlags.SectorEndOffset = 00616 NewSectionSize->LowPart & MM4K_MASK; 00617 00618 #if DBG 00619 MiSubsectionConsistent(ExtendedSubsection); 00620 #endif 00621 00622 ExtendedSubsection->SubsectionBase = ExtendedPtes; 00623 00624 PointerPte = ExtendedPtes; 00625 LastPte = ExtendedPtes + (AllocationSize / sizeof(MMPTE)); 00626 00627 if (ControlArea->FilePointer != NULL) { 00628 TempPte.u.Long = MiGetSubsectionAddressForPte(ExtendedSubsection); 00629 } 00630 #if DBG 00631 else { 00632 DbgPrint("MM: Extend with no control area file pointer %x %x\n", 00633 ExtendedSubsection, ControlArea); 00634 DbgBreakPoint(); 00635 } 00636 #endif 00637 00638 TempPte.u.Soft.Protection = ControlArea->Segment->SegmentPteTemplate.u.Soft.Protection; 00639 TempPte.u.Soft.Prototype = 1; 00640 ExtendedSubsection->u.SubsectionFlags.Protection = 00641 MI_GET_PROTECTION_FROM_SOFT_PTE(&TempPte); 00642 00643 while (PointerPte < LastPte) { 00644 MI_WRITE_INVALID_PTE (PointerPte, TempPte); 00645 PointerPte += 1; 00646 } 00647 00648 // 00649 // Link this into the list. 00650 // 00651 00652 LastSubsection->NextSubsection = ExtendedSubsection; 00653 ControlArea->Segment->TotalNumberOfPtes += RequiredPtes; 00654 00655 #if defined(_ALPHA_) && !defined(NT_UP) 00656 // 00657 // A memory barrier is required here to synchronize with 00658 // NtMapViewOfSection, which validates the specified offset against 00659 // the section object without holding lock synchronization. 00660 // This memory barrier forces the subsection chaining to be correct 00661 // before increasing the size in the section object. 00662 // 00663 __MB(); 00664 #endif 00665 00666 } 00667 00668 ControlArea->Segment->SizeOfSegment = *(PUINT64)NewSectionSize; 00669 Section->SizeOfSection = *NewSectionSize; 00670 00671 ReleaseAndReturnSuccess: 00672 00673 Status = STATUS_SUCCESS; 00674 00675 ReleaseAndReturn: 00676 00677 ExReleaseResource (&MmSectionExtendResource); 00678 KeLeaveCriticalRegion (); 00679 00680 return Status; 00681 }

NTSTATUS NtExtendSection IN HANDLE  SectionHandle,
IN OUT PLARGE_INTEGER  NewSectionSize
 

Definition at line 85 of file extsect.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, KernelMode, KPROCESSOR_MODE, MmExtendSection(), MmSectionObjectType, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, ProbeForWrite(), PSECTION, and Status.

00092 : 00093 00094 This function extends the size of the specified section. If 00095 the current size of the section is greater than or equal to the 00096 specified section size, the size is not updated. 00097 00098 Arguments: 00099 00100 SectionHandle - Supplies an open handle to a section object. 00101 00102 NewSectionSize - Supplies the new size for the section object. 00103 00104 Return Value: 00105 00106 Returns the status 00107 00108 TBS 00109 00110 00111 --*/ 00112 00113 { 00114 KPROCESSOR_MODE PreviousMode; 00115 PVOID Section; 00116 NTSTATUS Status; 00117 LARGE_INTEGER CapturedNewSectionSize; 00118 00119 PAGED_CODE(); 00120 00121 // 00122 // Check to make sure the new section size is accessible. 00123 // 00124 00125 PreviousMode = KeGetPreviousMode(); 00126 00127 if (PreviousMode != KernelMode) { 00128 00129 try { 00130 00131 ProbeForWrite (NewSectionSize, 00132 sizeof(LARGE_INTEGER), 00133 sizeof(ULONG )); 00134 00135 CapturedNewSectionSize = *NewSectionSize; 00136 00137 } except (EXCEPTION_EXECUTE_HANDLER) { 00138 00139 // 00140 // If an exception occurs during the probe or capture 00141 // of the initial values, then handle the exception and 00142 // return the exception code as the status value. 00143 // 00144 00145 return GetExceptionCode(); 00146 } 00147 00148 } else { 00149 00150 CapturedNewSectionSize = *NewSectionSize; 00151 } 00152 00153 // 00154 // Reference the section object. 00155 // 00156 00157 Status = ObReferenceObjectByHandle ( SectionHandle, 00158 SECTION_EXTEND_SIZE, 00159 MmSectionObjectType, 00160 PreviousMode, 00161 (PVOID *)&Section, 00162 NULL ); 00163 00164 if (!NT_SUCCESS(Status)) { 00165 return Status; 00166 } 00167 00168 // 00169 // Make sure this section is backed by a file. 00170 // 00171 00172 if (((PSECTION)Section)->Segment->ControlArea->FilePointer == NULL) { 00173 ObDereferenceObject (Section); 00174 return STATUS_SECTION_NOT_EXTENDED; 00175 } 00176 00177 Status = MmExtendSection (Section, &CapturedNewSectionSize, FALSE); 00178 00179 ObDereferenceObject (Section); 00180 00181 // 00182 // Update the NewSectionSize field. 00183 // 00184 00185 try { 00186 00187 // 00188 // Return the captured section size. 00189 // 00190 00191 *NewSectionSize = CapturedNewSectionSize; 00192 00193 } except (EXCEPTION_EXECUTE_HANDLER) { 00194 NOTHING; 00195 } 00196 00197 return Status; 00198 }


Generated on Sat May 15 19:43:36 2004 for test by doxygen 1.3.7