2 * Copyright (C) 1998-2005 ReactOS Team (and the authors from the programmers section)
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * PROJECT: ReactOS kernel
20 * FILE: ntoskrnl/mm/section.c
21 * PURPOSE: Implements section objects
23 * PROGRAMMERS: Rex Jolliff
36 * Thomas Weidenmueller
37 * Gunnar Andre' Dalsnes
45 /* INCLUDES *****************************************************************/
53 #define DPRINTC DPRINT
55 extern KEVENT MpwThreadEvent
;
56 extern KSPIN_LOCK MiSectionPageTableLock
;
58 /* GLOBALS *******************************************************************/
60 ULONG_PTR MmSubsectionBase
;
61 BOOLEAN MmAllocationFragment
;
66 (PFILE_OBJECT FileObject
,
67 PLARGE_INTEGER FileOffset
,
70 PIO_STATUS_BLOCK ReadStatus
);
72 static const INFORMATION_CLASS_INFO ExSectionInfoClass
[] =
74 ICI_SQ_SAME( sizeof(SECTION_BASIC_INFORMATION
), sizeof(ULONG
), ICIF_QUERY
), /* SectionBasicInformation */
75 ICI_SQ_SAME( sizeof(SECTION_IMAGE_INFORMATION
), sizeof(ULONG
), ICIF_QUERY
), /* SectionImageInformation */
78 /* FUNCTIONS *****************************************************************/
80 /* Note: Mmsp prefix denotes "Memory Manager Section Private". */
84 _MmLockCacheSectionSegment(PMM_CACHE_SECTION_SEGMENT Segment
, const char *file
, int line
)
86 DPRINT("MmLockSectionSegment(%p,%s:%d)\n", Segment
, file
, line
);
87 ExAcquireFastMutex(&Segment
->Lock
);
92 _MmUnlockCacheSectionSegment(PMM_CACHE_SECTION_SEGMENT Segment
, const char *file
, int line
)
94 ExReleaseFastMutex(&Segment
->Lock
);
95 DPRINT("MmUnlockSectionSegment(%p,%s:%d)\n", Segment
, file
, line
);
102 PLARGE_INTEGER FileOffsetPtr
,
106 PMMSUPPORT AddressSpace
;
107 PMEMORY_AREA MemoryArea
;
108 PMM_CACHE_SECTION_SEGMENT Segment
;
109 LARGE_INTEGER FileOffset
= *FileOffsetPtr
, End
, FirstMapped
;
110 DPRINT("MiZeroFillSection(Address %x,Offset %x,Length %x)\n", Address
, FileOffset
.LowPart
, Length
);
111 AddressSpace
= MmGetKernelAddressSpace();
112 MmLockAddressSpace(AddressSpace
);
113 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, Address
);
114 MmUnlockAddressSpace(AddressSpace
);
115 if (!MemoryArea
|| MemoryArea
->Type
!= MEMORY_AREA_SECTION_VIEW
)
117 return STATUS_NOT_MAPPED_DATA
;
120 Segment
= MemoryArea
->Data
.CacheData
.Segment
;
121 End
.QuadPart
= FileOffset
.QuadPart
+ Length
;
122 End
.LowPart
= PAGE_ROUND_DOWN(End
.LowPart
);
123 FileOffset
.LowPart
= PAGE_ROUND_UP(FileOffset
.LowPart
);
124 FirstMapped
.QuadPart
= MemoryArea
->Data
.CacheData
.ViewOffset
.QuadPart
;
126 ("Pulling zero pages for %08x%08x-%08x%08x\n",
127 FileOffset
.u
.HighPart
, FileOffset
.u
.LowPart
,
128 End
.u
.HighPart
, End
.u
.LowPart
);
129 while (FileOffset
.QuadPart
< End
.QuadPart
)
134 if (!NT_SUCCESS(MmRequestPageMemoryConsumer(MC_CACHE
, TRUE
, &Page
)))
137 MmLockAddressSpace(AddressSpace
);
138 MmLockCacheSectionSegment(Segment
);
140 Entry
= MiGetPageEntryCacheSectionSegment(Segment
, &FileOffset
);
143 MiSetPageEntryCacheSectionSegment(Segment
, &FileOffset
, MAKE_PFN_SSE(Page
));
144 Address
= ((PCHAR
)MemoryArea
->StartingAddress
) + FileOffset
.QuadPart
- FirstMapped
.QuadPart
;
145 MmReferencePage(Page
);
146 MmCreateVirtualMapping(NULL
, Address
, PAGE_READWRITE
, &Page
, 1);
147 MmInsertRmap(Page
, NULL
, Address
);
150 MmReleasePageMemoryConsumer(MC_CACHE
, Page
);
152 MmUnlockCacheSectionSegment(Segment
);
153 MmUnlockAddressSpace(AddressSpace
);
155 FileOffset
.QuadPart
+= PAGE_SIZE
;
157 return STATUS_SUCCESS
;
162 _MiFlushMappedSection
164 PLARGE_INTEGER BaseOffset
,
165 PLARGE_INTEGER FileSize
,
170 NTSTATUS Status
= STATUS_SUCCESS
;
171 ULONG_PTR PageAddress
;
172 PMMSUPPORT AddressSpace
= MmGetKernelAddressSpace();
173 PMEMORY_AREA MemoryArea
;
174 PMM_CACHE_SECTION_SEGMENT Segment
;
175 ULONG_PTR BeginningAddress
, EndingAddress
;
176 LARGE_INTEGER ViewOffset
;
177 LARGE_INTEGER FileOffset
;
181 DPRINT("MiFlushMappedSection(%x,%08x,%x,%d,%s:%d)\n", BaseAddress
, BaseOffset
->LowPart
, FileSize
, WriteData
, File
, Line
);
183 MmLockAddressSpace(AddressSpace
);
184 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, BaseAddress
);
185 if (!MemoryArea
|| MemoryArea
->Type
!= MEMORY_AREA_CACHE
)
187 MmUnlockAddressSpace(AddressSpace
);
188 DPRINT("STATUS_NOT_MAPPED_DATA\n");
189 return STATUS_NOT_MAPPED_DATA
;
191 BeginningAddress
= PAGE_ROUND_DOWN((ULONG_PTR
)MemoryArea
->StartingAddress
);
192 EndingAddress
= PAGE_ROUND_UP((ULONG_PTR
)MemoryArea
->EndingAddress
);
193 Segment
= MemoryArea
->Data
.CacheData
.Segment
;
194 ViewOffset
.QuadPart
= MemoryArea
->Data
.CacheData
.ViewOffset
.QuadPart
;
196 ASSERT(ViewOffset
.QuadPart
== BaseOffset
->QuadPart
);
198 MmLockCacheSectionSegment(Segment
);
200 Pages
= ExAllocatePool
203 ((EndingAddress
- BeginningAddress
) >> PAGE_SHIFT
));
210 DPRINT("Getting pages in range %08x-%08x\n", BeginningAddress
, EndingAddress
);
212 for (PageAddress
= BeginningAddress
;
213 PageAddress
< EndingAddress
;
214 PageAddress
+= PAGE_SIZE
)
217 FileOffset
.QuadPart
= ViewOffset
.QuadPart
+ PageAddress
- BeginningAddress
;
219 MiGetPageEntryCacheSectionSegment
220 (MemoryArea
->Data
.CacheData
.Segment
,
222 Page
= PFN_FROM_SSE(Entry
);
223 if (Entry
!= 0 && !IS_SWAP_FROM_SSE(Entry
) &&
224 (MmIsDirtyPageRmap(Page
) || IS_DIRTY_SSE(Entry
)) &&
225 FileOffset
.QuadPart
< FileSize
->QuadPart
)
227 Pages
[(PageAddress
- BeginningAddress
) >> PAGE_SHIFT
] = Page
;
230 Pages
[(PageAddress
- BeginningAddress
) >> PAGE_SHIFT
] = 0;
233 MmUnlockCacheSectionSegment(Segment
);
234 MmUnlockAddressSpace(AddressSpace
);
236 for (PageAddress
= BeginningAddress
;
237 PageAddress
< EndingAddress
;
238 PageAddress
+= PAGE_SIZE
)
240 FileOffset
.QuadPart
= ViewOffset
.QuadPart
+ PageAddress
- BeginningAddress
;
241 Page
= Pages
[(PageAddress
- BeginningAddress
) >> PAGE_SHIFT
];
246 DPRINT("MiWriteBackPage(%wZ,addr %x,%08x%08x)\n", &Segment
->FileObject
->FileName
, PageAddress
, FileOffset
.u
.HighPart
, FileOffset
.u
.LowPart
);
247 Status
= MiWriteBackPage(Segment
->FileObject
, &FileOffset
, PAGE_SIZE
, Page
);
249 Status
= STATUS_SUCCESS
;
251 if (NT_SUCCESS(Status
)) {
252 MmLockAddressSpace(AddressSpace
);
253 MmSetCleanAllRmaps(Page
);
254 MmLockCacheSectionSegment(Segment
);
255 Entry
= MiGetPageEntryCacheSectionSegment(Segment
, &FileOffset
);
256 if (Entry
&& !IS_SWAP_FROM_SSE(Entry
) && PFN_FROM_SSE(Entry
) == Page
)
257 MiSetPageEntryCacheSectionSegment(Segment
, &FileOffset
, CLEAN_SSE(Entry
));
258 MmUnlockCacheSectionSegment(Segment
);
259 MmUnlockAddressSpace(AddressSpace
);
262 ("Writeback from section flush %08x%08x (%x) %x@%x (%08x%08x:%wZ) failed %x\n",
263 FileOffset
.u
.HighPart
, FileOffset
.u
.LowPart
,
264 (ULONG
)(FileSize
->QuadPart
- FileOffset
.QuadPart
),
267 FileSize
->u
.HighPart
,
269 &Segment
->FileObject
->FileName
,
282 MmFinalizeSegment(PMM_CACHE_SECTION_SEGMENT Segment
)
286 MmLockCacheSectionSegment(Segment
);
287 if (Segment
->Flags
& MM_DATAFILE_SEGMENT
) {
288 KeAcquireSpinLock(&Segment
->FileObject
->IrpListLock
, &OldIrql
);
289 if (Segment
->Flags
& MM_SEGMENT_FINALIZE
) {
290 KeReleaseSpinLock(&Segment
->FileObject
->IrpListLock
, OldIrql
);
291 MmUnlockCacheSectionSegment(Segment
);
294 Segment
->Flags
|= MM_SEGMENT_FINALIZE
;
297 DPRINTC("Finalizing segment %x\n", Segment
);
298 if (Segment
->Flags
& MM_DATAFILE_SEGMENT
)
300 //Segment->FileObject->SectionObjectPointer->DataSectionObject = NULL;
301 KeReleaseSpinLock(&Segment
->FileObject
->IrpListLock
, OldIrql
);
302 MiFreePageTablesSectionSegment(Segment
, MiFreeSegmentPage
);
303 MmUnlockCacheSectionSegment(Segment
);
304 ObDereferenceObject(Segment
->FileObject
);
306 MiFreePageTablesSectionSegment(Segment
, MiFreeSegmentPage
);
307 MmUnlockCacheSectionSegment(Segment
);
309 DPRINTC("Segment %x destroy\n", Segment
);
316 (PMM_CACHE_SECTION_SEGMENT
*SegmentObject
,
317 ACCESS_MASK DesiredAccess
,
318 POBJECT_ATTRIBUTES ObjectAttributes
,
319 PLARGE_INTEGER UMaximumSize
,
320 ULONG SectionPageProtection
,
321 ULONG AllocationAttributes
,
322 PFILE_OBJECT FileObject
)
324 * Create a section backed by a data file
328 ULARGE_INTEGER MaximumSize
;
329 PMM_CACHE_SECTION_SEGMENT Segment
;
331 IO_STATUS_BLOCK Iosb
;
332 CC_FILE_SIZES FileSizes
;
333 FILE_STANDARD_INFORMATION FileInfo
;
336 * Check file access required
338 if (SectionPageProtection
& PAGE_READWRITE
||
339 SectionPageProtection
& PAGE_EXECUTE_READWRITE
)
341 FileAccess
= FILE_READ_DATA
| FILE_WRITE_DATA
;
345 FileAccess
= FILE_READ_DATA
;
349 * Reference the file handle
351 ObReferenceObject(FileObject
);
353 DPRINT("Getting original file size\n");
354 /* A hack: If we're cached, we can overcome deadlocking with the upper
355 * layer filesystem call by retriving the object sizes from the cache
356 * which is made to keep track. If I had to guess, they were figuring
357 * out a similar problem.
359 if (!CcGetFileSizes(FileObject
, &FileSizes
))
362 * FIXME: This is propably not entirely correct. We can't look into
363 * the standard FCB header because it might not be initialized yet
364 * (as in case of the EXT2FS driver by Manoj Paul Joseph where the
365 * standard file information is filled on first request).
367 Status
= IoQueryFileInformation
369 FileStandardInformation
,
370 sizeof(FILE_STANDARD_INFORMATION
),
374 if (!NT_SUCCESS(Status
))
379 ASSERT(Status
!= STATUS_PENDING
);
381 FileSizes
.ValidDataLength
= FileInfo
.EndOfFile
;
382 FileSizes
.FileSize
= FileInfo
.EndOfFile
;
384 DPRINT("Got %08x\n", FileSizes
.ValidDataLength
.u
.LowPart
);
387 * FIXME: Revise this once a locking order for file size changes is
390 if (UMaximumSize
!= NULL
)
392 MaximumSize
.QuadPart
= UMaximumSize
->QuadPart
;
396 DPRINT("Got file size %08x%08x\n", FileSizes
.FileSize
.u
.HighPart
, FileSizes
.FileSize
.u
.LowPart
);
397 MaximumSize
.QuadPart
= FileSizes
.FileSize
.QuadPart
;
400 Segment
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(MM_CACHE_SECTION_SEGMENT
),
401 TAG_MM_SECTION_SEGMENT
);
404 return(STATUS_NO_MEMORY
);
407 ExInitializeFastMutex(&Segment
->Lock
);
409 Segment
->ReferenceCount
= 1;
412 * Set the lock before assigning the segment to the file object
414 ExAcquireFastMutex(&Segment
->Lock
);
416 DPRINT("Filling out Segment info (No previous data section)\n");
417 ObReferenceObject(FileObject
);
418 Segment
->FileObject
= FileObject
;
419 Segment
->Protection
= SectionPageProtection
;
420 Segment
->Flags
= MM_DATAFILE_SEGMENT
;
421 memset(&Segment
->Image
, 0, sizeof(Segment
->Image
));
422 Segment
->WriteCopy
= FALSE
;
423 if (AllocationAttributes
& SEC_RESERVE
)
425 Segment
->Length
.QuadPart
= Segment
->RawLength
.QuadPart
= 0;
429 Segment
->RawLength
= MaximumSize
;
430 Segment
->Length
.QuadPart
= PAGE_ROUND_UP(Segment
->RawLength
.QuadPart
);
433 MiInitializeSectionPageTable(Segment
);
434 MmUnlockCacheSectionSegment(Segment
);
436 /* Extend file if section is longer */
437 DPRINT("MaximumSize %08x%08x ValidDataLength %08x%08x\n",
438 MaximumSize
.u
.HighPart
, MaximumSize
.u
.LowPart
,
439 FileSizes
.ValidDataLength
.u
.HighPart
, FileSizes
.ValidDataLength
.u
.LowPart
);
440 if (MaximumSize
.QuadPart
> FileSizes
.ValidDataLength
.QuadPart
)
442 DPRINT("Changing file size to %08x%08x, segment %x\n", MaximumSize
.u
.HighPart
, MaximumSize
.u
.LowPart
, Segment
);
443 Status
= IoSetInformation(FileObject
, FileEndOfFileInformation
, sizeof(LARGE_INTEGER
), &MaximumSize
);
444 DPRINT("Change: Status %x\n", Status
);
445 if (!NT_SUCCESS(Status
))
447 DPRINT("Could not expand section\n");
452 DPRINTC("Segment %x created (%x)\n", Segment
, Segment
->Flags
);
454 *SegmentObject
= Segment
;
456 return(STATUS_SUCCESS
);
462 (PMMSUPPORT AddressSpace
,
463 PMM_CACHE_SECTION_SEGMENT Segment
,
467 PLARGE_INTEGER ViewOffset
,
468 ULONG AllocationType
,
474 PHYSICAL_ADDRESS BoundaryAddressMultiple
;
476 BoundaryAddressMultiple
.QuadPart
= 0;
478 Status
= MmCreateMemoryArea
487 BoundaryAddressMultiple
);
489 if (!NT_SUCCESS(Status
))
491 DPRINT("Mapping between 0x%.8X and 0x%.8X failed (%X).\n",
492 (*BaseAddress
), (char*)(*BaseAddress
) + ViewSize
, Status
);
496 DPRINTC("MiMapViewOfSegment %x %x %x %x %x %wZ %s:%d\n", MmGetAddressSpaceOwner(AddressSpace
), *BaseAddress
, Segment
, ViewOffset
? ViewOffset
->LowPart
: 0, ViewSize
, Segment
->FileObject
? &Segment
->FileObject
->FileName
: NULL
, file
, line
);
498 MArea
->Data
.CacheData
.Segment
= Segment
;
500 MArea
->Data
.CacheData
.ViewOffset
= *ViewOffset
;
502 MArea
->Data
.CacheData
.ViewOffset
.QuadPart
= 0;
505 MArea
->NotPresent
= MmNotPresentFaultPageFile
;
506 MArea
->AccessFault
= MiCowSectionPage
;
507 MArea
->PageOut
= MmPageOutPageFileView
;
511 ("MiMapViewOfSegment(P %x, A %x, T %x)\n",
512 MmGetAddressSpaceOwner(AddressSpace
), *BaseAddress
, MArea
->Type
);
514 return(STATUS_SUCCESS
);
520 (PMM_CACHE_SECTION_SEGMENT Segment
,
521 PLARGE_INTEGER FileOffset
)
524 PFILE_OBJECT FileObject
= Segment
->FileObject
;
526 Entry
= MiGetPageEntryCacheSectionSegment(Segment
, FileOffset
);
527 DPRINTC("MiFreeSegmentPage(%x:%08x%08x -> Entry %x\n",
528 Segment
, FileOffset
->HighPart
, FileOffset
->LowPart
, Entry
);
530 if (Entry
&& !IS_SWAP_FROM_SSE(Entry
))
532 // The segment is carrying a dirty page.
533 PFN_NUMBER OldPage
= PFN_FROM_SSE(Entry
);
534 if (IS_DIRTY_SSE(Entry
) && FileObject
)
536 DPRINT("MiWriteBackPage(%x,%wZ,%08x%08x)\n", Segment
, &FileObject
->FileName
, FileOffset
->u
.HighPart
, FileOffset
->u
.LowPart
);
537 MiWriteBackPage(FileObject
, FileOffset
, PAGE_SIZE
, OldPage
);
539 DPRINTC("Free page %x (off %x from %x) (ref ct %d, ent %x, dirty? %s)\n", OldPage
, FileOffset
->LowPart
, Segment
, MmGetReferenceCountPage(OldPage
), Entry
, IS_DIRTY_SSE(Entry
) ? "true" : "false");
541 MiSetPageEntryCacheSectionSegment(Segment
, FileOffset
, 0);
542 MmReleasePageMemoryConsumer(MC_CACHE
, OldPage
);
544 else if (IS_SWAP_FROM_SSE(Entry
))
546 DPRINT("Free swap\n");
547 MmFreeSwapPage(SWAPENTRY_FROM_SSE(Entry
));
554 MmFreeCacheSectionPage
555 (PVOID Context
, MEMORY_AREA
* MemoryArea
, PVOID Address
,
556 PFN_NUMBER Page
, SWAPENTRY SwapEntry
, BOOLEAN Dirty
)
559 PVOID
*ContextData
= Context
;
560 PMMSUPPORT AddressSpace
;
562 PMM_CACHE_SECTION_SEGMENT Segment
;
563 LARGE_INTEGER Offset
;
565 DPRINT("MmFreeSectionPage(%x,%x,%x,%x,%d)\n", MmGetAddressSpaceOwner(ContextData
[0]), Address
, Page
, SwapEntry
, Dirty
);
567 AddressSpace
= ContextData
[0];
568 Process
= MmGetAddressSpaceOwner(AddressSpace
);
569 Address
= (PVOID
)PAGE_ROUND_DOWN(Address
);
570 Segment
= ContextData
[1];
571 Offset
.QuadPart
= (ULONG_PTR
)Address
- (ULONG_PTR
)MemoryArea
->StartingAddress
+
572 MemoryArea
->Data
.CacheData
.ViewOffset
.QuadPart
;
574 Entry
= MiGetPageEntryCacheSectionSegment(Segment
, &Offset
);
578 DPRINT("Removing page %x:%x -> %x\n", Segment
, Offset
.LowPart
, Entry
);
579 MmSetSavedSwapEntryPage(Page
, 0);
580 MmDeleteRmap(Page
, Process
, Address
);
581 MmDeleteVirtualMapping(Process
, Address
, FALSE
, NULL
, NULL
);
582 MmReleasePageMemoryConsumer(MC_CACHE
, Page
);
584 if (Page
!= 0 && PFN_FROM_SSE(Entry
) == Page
&& Dirty
)
586 DPRINT("Freeing section page %x:%x -> %x\n", Segment
, Offset
.LowPart
, Entry
);
587 MiSetPageEntryCacheSectionSegment(Segment
, &Offset
, DIRTY_SSE(Entry
));
589 else if (SwapEntry
!= 0)
591 MmFreeSwapPage(SwapEntry
);
597 MmUnmapViewOfCacheSegment
598 (PMMSUPPORT AddressSpace
,
602 PMEMORY_AREA MemoryArea
;
603 PMM_CACHE_SECTION_SEGMENT Segment
;
605 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, BaseAddress
);
606 if (MemoryArea
== NULL
)
609 return(STATUS_UNSUCCESSFUL
);
612 MemoryArea
->DeleteInProgress
= TRUE
;
613 Segment
= MemoryArea
->Data
.CacheData
.Segment
;
614 MemoryArea
->Data
.CacheData
.Segment
= NULL
;
616 MmLockCacheSectionSegment(Segment
);
618 Context
[0] = AddressSpace
;
619 Context
[1] = Segment
;
620 DPRINT("MmFreeMemoryArea(%x,%x)\n", MmGetAddressSpaceOwner(AddressSpace
), MemoryArea
->StartingAddress
);
621 MmFreeMemoryArea(AddressSpace
, MemoryArea
, MmFreeCacheSectionPage
, Context
);
623 MmUnlockCacheSectionSegment(Segment
);
625 DPRINTC("MiUnmapViewOfSegment %x %x %x\n", MmGetAddressSpaceOwner(AddressSpace
), BaseAddress
, Segment
);
627 return(STATUS_SUCCESS
);
633 (PMM_CACHE_SECTION_SEGMENT Segment
,
634 PLARGE_INTEGER NewSize
,
637 LARGE_INTEGER OldSize
;
638 DPRINT("Extend Segment %x\n", Segment
);
640 MmLockCacheSectionSegment(Segment
);
641 OldSize
.QuadPart
= Segment
->RawLength
.QuadPart
;
642 MmUnlockCacheSectionSegment(Segment
);
644 DPRINT("OldSize %08x%08x NewSize %08x%08x\n",
645 OldSize
.u
.HighPart
, OldSize
.u
.LowPart
,
646 NewSize
->u
.HighPart
, NewSize
->u
.LowPart
);
648 if (ExtendFile
&& OldSize
.QuadPart
< NewSize
->QuadPart
)
651 Status
= IoSetInformation(Segment
->FileObject
, FileEndOfFileInformation
, sizeof(LARGE_INTEGER
), NewSize
);
652 if (!NT_SUCCESS(Status
)) return Status
;
655 MmLockCacheSectionSegment(Segment
);
656 Segment
->RawLength
.QuadPart
= NewSize
->QuadPart
;
657 Segment
->Length
.QuadPart
= MAX(Segment
->Length
.QuadPart
, PAGE_ROUND_UP(Segment
->RawLength
.LowPart
));
658 MmUnlockCacheSectionSegment(Segment
);
659 return STATUS_SUCCESS
;
664 MmMapCacheViewInSystemSpaceAtOffset
665 (IN PMM_CACHE_SECTION_SEGMENT Segment
,
666 OUT PVOID
*MappedBase
,
667 PLARGE_INTEGER FileOffset
,
668 IN OUT PULONG ViewSize
)
670 PMMSUPPORT AddressSpace
;
673 DPRINT("MmMapViewInSystemSpaceAtOffset() called offset %08x%08x\n", FileOffset
->HighPart
, FileOffset
->LowPart
);
675 AddressSpace
= MmGetKernelAddressSpace();
677 MmLockAddressSpace(AddressSpace
);
678 MmLockCacheSectionSegment(Segment
);
680 Status
= MiMapViewOfSegment
689 MmUnlockCacheSectionSegment(Segment
);
690 MmUnlockAddressSpace(AddressSpace
);
699 MmUnmapCacheViewInSystemSpace (IN PVOID MappedBase
)
701 PMMSUPPORT AddressSpace
;
704 DPRINT("MmUnmapViewInSystemSpace() called\n");
706 AddressSpace
= MmGetKernelAddressSpace();
708 Status
= MmUnmapViewOfCacheSegment(AddressSpace
, MappedBase
);