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
;
65 (PFILE_OBJECT FileObject
,
66 PLARGE_INTEGER FileOffset
,
69 PIO_STATUS_BLOCK ReadStatus
);
71 static const INFORMATION_CLASS_INFO ExSectionInfoClass
[] =
73 ICI_SQ_SAME( sizeof(SECTION_BASIC_INFORMATION
), sizeof(ULONG
), ICIF_QUERY
), /* SectionBasicInformation */
74 ICI_SQ_SAME( sizeof(SECTION_IMAGE_INFORMATION
), sizeof(ULONG
), ICIF_QUERY
), /* SectionImageInformation */
77 /* FUNCTIONS *****************************************************************/
79 /* Note: Mmsp prefix denotes "Memory Manager Section Private". */
83 _MmLockCacheSectionSegment(PMM_CACHE_SECTION_SEGMENT Segment
, const char *file
, int line
)
85 DPRINT("MmLockSectionSegment(%p,%s:%d)\n", Segment
, file
, line
);
86 ExAcquireFastMutex(&Segment
->Lock
);
91 _MmUnlockCacheSectionSegment(PMM_CACHE_SECTION_SEGMENT Segment
, const char *file
, int line
)
93 ExReleaseFastMutex(&Segment
->Lock
);
94 DPRINT("MmUnlockSectionSegment(%p,%s:%d)\n", Segment
, file
, line
);
101 PLARGE_INTEGER FileOffsetPtr
,
105 PMMSUPPORT AddressSpace
;
106 PMEMORY_AREA MemoryArea
;
107 PMM_CACHE_SECTION_SEGMENT Segment
;
108 LARGE_INTEGER FileOffset
= *FileOffsetPtr
, End
, FirstMapped
;
109 DPRINT("MiZeroFillSection(Address %x,Offset %x,Length %x)\n", Address
, FileOffset
.LowPart
, Length
);
110 AddressSpace
= MmGetKernelAddressSpace();
111 MmLockAddressSpace(AddressSpace
);
112 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, Address
);
113 MmUnlockAddressSpace(AddressSpace
);
114 if (!MemoryArea
|| MemoryArea
->Type
!= MEMORY_AREA_SECTION_VIEW
)
116 return STATUS_NOT_MAPPED_DATA
;
119 Segment
= MemoryArea
->Data
.CacheData
.Segment
;
120 End
.QuadPart
= FileOffset
.QuadPart
+ Length
;
121 End
.LowPart
= PAGE_ROUND_DOWN(End
.LowPart
);
122 FileOffset
.LowPart
= PAGE_ROUND_UP(FileOffset
.LowPart
);
123 FirstMapped
.QuadPart
= MemoryArea
->Data
.CacheData
.ViewOffset
.QuadPart
;
125 ("Pulling zero pages for %08x%08x-%08x%08x\n",
126 FileOffset
.u
.HighPart
, FileOffset
.u
.LowPart
,
127 End
.u
.HighPart
, End
.u
.LowPart
);
128 while (FileOffset
.QuadPart
< End
.QuadPart
)
133 if (!NT_SUCCESS(MmRequestPageMemoryConsumer(MC_CACHE
, TRUE
, &Page
)))
136 MmLockAddressSpace(AddressSpace
);
137 MmLockCacheSectionSegment(Segment
);
139 Entry
= MiGetPageEntryCacheSectionSegment(Segment
, &FileOffset
);
142 MiSetPageEntryCacheSectionSegment(Segment
, &FileOffset
, MAKE_PFN_SSE(Page
));
143 Address
= ((PCHAR
)MemoryArea
->StartingAddress
) + FileOffset
.QuadPart
- FirstMapped
.QuadPart
;
144 MmReferencePage(Page
);
145 MmCreateVirtualMapping(NULL
, Address
, PAGE_READWRITE
, &Page
, 1);
146 MmInsertRmap(Page
, NULL
, Address
);
149 MmReleasePageMemoryConsumer(MC_CACHE
, Page
);
151 MmUnlockCacheSectionSegment(Segment
);
152 MmUnlockAddressSpace(AddressSpace
);
154 FileOffset
.QuadPart
+= PAGE_SIZE
;
156 return STATUS_SUCCESS
;
161 _MiFlushMappedSection
163 PLARGE_INTEGER BaseOffset
,
164 PLARGE_INTEGER FileSize
,
169 NTSTATUS Status
= STATUS_SUCCESS
;
170 ULONG_PTR PageAddress
;
171 PMMSUPPORT AddressSpace
= MmGetKernelAddressSpace();
172 PMEMORY_AREA MemoryArea
;
173 PMM_CACHE_SECTION_SEGMENT Segment
;
174 ULONG_PTR BeginningAddress
, EndingAddress
;
175 LARGE_INTEGER ViewOffset
;
176 LARGE_INTEGER FileOffset
;
180 DPRINT("MiFlushMappedSection(%x,%08x,%x,%d,%s:%d)\n", BaseAddress
, BaseOffset
->LowPart
, FileSize
, WriteData
, File
, Line
);
182 MmLockAddressSpace(AddressSpace
);
183 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, BaseAddress
);
184 if (!MemoryArea
|| MemoryArea
->Type
!= MEMORY_AREA_CACHE
)
186 MmUnlockAddressSpace(AddressSpace
);
187 DPRINT("STATUS_NOT_MAPPED_DATA\n");
188 return STATUS_NOT_MAPPED_DATA
;
190 BeginningAddress
= PAGE_ROUND_DOWN((ULONG_PTR
)MemoryArea
->StartingAddress
);
191 EndingAddress
= PAGE_ROUND_UP((ULONG_PTR
)MemoryArea
->EndingAddress
);
192 Segment
= MemoryArea
->Data
.CacheData
.Segment
;
193 ViewOffset
.QuadPart
= MemoryArea
->Data
.CacheData
.ViewOffset
.QuadPart
;
195 ASSERT(ViewOffset
.QuadPart
== BaseOffset
->QuadPart
);
197 MmLockCacheSectionSegment(Segment
);
199 Pages
= ExAllocatePool
202 ((EndingAddress
- BeginningAddress
) >> PAGE_SHIFT
));
209 DPRINT("Getting pages in range %08x-%08x\n", BeginningAddress
, EndingAddress
);
211 for (PageAddress
= BeginningAddress
;
212 PageAddress
< EndingAddress
;
213 PageAddress
+= PAGE_SIZE
)
216 FileOffset
.QuadPart
= ViewOffset
.QuadPart
+ PageAddress
- BeginningAddress
;
218 MiGetPageEntryCacheSectionSegment
219 (MemoryArea
->Data
.CacheData
.Segment
,
221 Page
= PFN_FROM_SSE(Entry
);
222 if (Entry
!= 0 && !IS_SWAP_FROM_SSE(Entry
) &&
223 (MmIsDirtyPageRmap(Page
) || IS_DIRTY_SSE(Entry
)) &&
224 FileOffset
.QuadPart
< FileSize
->QuadPart
)
226 Pages
[(PageAddress
- BeginningAddress
) >> PAGE_SHIFT
] = Page
;
229 Pages
[(PageAddress
- BeginningAddress
) >> PAGE_SHIFT
] = 0;
232 MmUnlockCacheSectionSegment(Segment
);
233 MmUnlockAddressSpace(AddressSpace
);
235 for (PageAddress
= BeginningAddress
;
236 PageAddress
< EndingAddress
;
237 PageAddress
+= PAGE_SIZE
)
239 FileOffset
.QuadPart
= ViewOffset
.QuadPart
+ PageAddress
- BeginningAddress
;
240 Page
= Pages
[(PageAddress
- BeginningAddress
) >> PAGE_SHIFT
];
245 DPRINT("MiWriteBackPage(%wZ,addr %x,%08x%08x)\n", &Segment
->FileObject
->FileName
, PageAddress
, FileOffset
.u
.HighPart
, FileOffset
.u
.LowPart
);
246 Status
= MiWriteBackPage(Segment
->FileObject
, &FileOffset
, PAGE_SIZE
, Page
);
248 Status
= STATUS_SUCCESS
;
250 if (NT_SUCCESS(Status
)) {
251 MmLockAddressSpace(AddressSpace
);
252 MmSetCleanAllRmaps(Page
);
253 MmLockCacheSectionSegment(Segment
);
254 Entry
= MiGetPageEntryCacheSectionSegment(Segment
, &FileOffset
);
255 if (Entry
&& !IS_SWAP_FROM_SSE(Entry
) && PFN_FROM_SSE(Entry
) == Page
)
256 MiSetPageEntryCacheSectionSegment(Segment
, &FileOffset
, CLEAN_SSE(Entry
));
257 MmUnlockCacheSectionSegment(Segment
);
258 MmUnlockAddressSpace(AddressSpace
);
261 ("Writeback from section flush %08x%08x (%x) %x@%x (%08x%08x:%wZ) failed %x\n",
262 FileOffset
.u
.HighPart
, FileOffset
.u
.LowPart
,
263 (ULONG
)(FileSize
->QuadPart
- FileOffset
.QuadPart
),
266 FileSize
->u
.HighPart
,
268 &Segment
->FileObject
->FileName
,
281 MmFinalizeSegment(PMM_CACHE_SECTION_SEGMENT Segment
)
285 MmLockCacheSectionSegment(Segment
);
286 if (Segment
->Flags
& MM_DATAFILE_SEGMENT
) {
287 KeAcquireSpinLock(&Segment
->FileObject
->IrpListLock
, &OldIrql
);
288 if (Segment
->Flags
& MM_SEGMENT_FINALIZE
) {
289 KeReleaseSpinLock(&Segment
->FileObject
->IrpListLock
, OldIrql
);
290 MmUnlockCacheSectionSegment(Segment
);
293 Segment
->Flags
|= MM_SEGMENT_FINALIZE
;
296 DPRINTC("Finalizing segment %x\n", Segment
);
297 if (Segment
->Flags
& MM_DATAFILE_SEGMENT
)
299 //Segment->FileObject->SectionObjectPointer->DataSectionObject = NULL;
300 KeReleaseSpinLock(&Segment
->FileObject
->IrpListLock
, OldIrql
);
301 MiFreePageTablesSectionSegment(Segment
, MiFreeSegmentPage
);
302 MmUnlockCacheSectionSegment(Segment
);
303 ObDereferenceObject(Segment
->FileObject
);
305 MiFreePageTablesSectionSegment(Segment
, MiFreeSegmentPage
);
306 MmUnlockCacheSectionSegment(Segment
);
308 DPRINTC("Segment %x destroy\n", Segment
);
309 ExFreePoolWithTag(Segment
, TAG_MM_SECTION_SEGMENT
);
315 (PMM_CACHE_SECTION_SEGMENT
*SegmentObject
,
316 ACCESS_MASK DesiredAccess
,
317 POBJECT_ATTRIBUTES ObjectAttributes
,
318 PLARGE_INTEGER UMaximumSize
,
319 ULONG SectionPageProtection
,
320 ULONG AllocationAttributes
,
321 PFILE_OBJECT FileObject
)
323 * Create a section backed by a data file
327 ULARGE_INTEGER MaximumSize
;
328 PMM_CACHE_SECTION_SEGMENT Segment
;
330 IO_STATUS_BLOCK Iosb
;
331 CC_FILE_SIZES FileSizes
;
332 FILE_STANDARD_INFORMATION FileInfo
;
335 * Check file access required
337 if (SectionPageProtection
& PAGE_READWRITE
||
338 SectionPageProtection
& PAGE_EXECUTE_READWRITE
)
340 FileAccess
= FILE_READ_DATA
| FILE_WRITE_DATA
;
344 FileAccess
= FILE_READ_DATA
;
348 * Reference the file handle
350 ObReferenceObject(FileObject
);
352 DPRINT("Getting original file size\n");
353 /* A hack: If we're cached, we can overcome deadlocking with the upper
354 * layer filesystem call by retriving the object sizes from the cache
355 * which is made to keep track. If I had to guess, they were figuring
356 * out a similar problem.
358 if (!CcGetFileSizes(FileObject
, &FileSizes
))
361 * FIXME: This is propably not entirely correct. We can't look into
362 * the standard FCB header because it might not be initialized yet
363 * (as in case of the EXT2FS driver by Manoj Paul Joseph where the
364 * standard file information is filled on first request).
366 Status
= IoQueryFileInformation
368 FileStandardInformation
,
369 sizeof(FILE_STANDARD_INFORMATION
),
373 if (!NT_SUCCESS(Status
))
378 ASSERT(Status
!= STATUS_PENDING
);
380 FileSizes
.ValidDataLength
= FileInfo
.EndOfFile
;
381 FileSizes
.FileSize
= FileInfo
.EndOfFile
;
383 DPRINT("Got %08x\n", FileSizes
.ValidDataLength
.u
.LowPart
);
386 * FIXME: Revise this once a locking order for file size changes is
389 if (UMaximumSize
!= NULL
)
391 MaximumSize
.QuadPart
= UMaximumSize
->QuadPart
;
395 DPRINT("Got file size %08x%08x\n", FileSizes
.FileSize
.u
.HighPart
, FileSizes
.FileSize
.u
.LowPart
);
396 MaximumSize
.QuadPart
= FileSizes
.FileSize
.QuadPart
;
399 Segment
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(MM_CACHE_SECTION_SEGMENT
),
400 TAG_MM_SECTION_SEGMENT
);
403 return(STATUS_NO_MEMORY
);
406 ExInitializeFastMutex(&Segment
->Lock
);
408 Segment
->ReferenceCount
= 1;
411 * Set the lock before assigning the segment to the file object
413 ExAcquireFastMutex(&Segment
->Lock
);
415 DPRINT("Filling out Segment info (No previous data section)\n");
416 ObReferenceObject(FileObject
);
417 Segment
->FileObject
= FileObject
;
418 Segment
->Protection
= SectionPageProtection
;
419 Segment
->Flags
= MM_DATAFILE_SEGMENT
;
420 memset(&Segment
->Image
, 0, sizeof(Segment
->Image
));
421 Segment
->WriteCopy
= FALSE
;
422 if (AllocationAttributes
& SEC_RESERVE
)
424 Segment
->Length
.QuadPart
= Segment
->RawLength
.QuadPart
= 0;
428 Segment
->RawLength
= MaximumSize
;
429 Segment
->Length
.QuadPart
= PAGE_ROUND_UP(Segment
->RawLength
.QuadPart
);
432 MiInitializeSectionPageTable(Segment
);
433 MmUnlockCacheSectionSegment(Segment
);
435 /* Extend file if section is longer */
436 DPRINT("MaximumSize %08x%08x ValidDataLength %08x%08x\n",
437 MaximumSize
.u
.HighPart
, MaximumSize
.u
.LowPart
,
438 FileSizes
.ValidDataLength
.u
.HighPart
, FileSizes
.ValidDataLength
.u
.LowPart
);
439 if (MaximumSize
.QuadPart
> FileSizes
.ValidDataLength
.QuadPart
)
441 DPRINT("Changing file size to %08x%08x, segment %x\n", MaximumSize
.u
.HighPart
, MaximumSize
.u
.LowPart
, Segment
);
442 Status
= IoSetInformation(FileObject
, FileEndOfFileInformation
, sizeof(LARGE_INTEGER
), &MaximumSize
);
443 DPRINT("Change: Status %x\n", Status
);
444 if (!NT_SUCCESS(Status
))
446 DPRINT("Could not expand section\n");
451 DPRINTC("Segment %x created (%x)\n", Segment
, Segment
->Flags
);
453 *SegmentObject
= Segment
;
455 return(STATUS_SUCCESS
);
461 (PMMSUPPORT AddressSpace
,
462 PMM_CACHE_SECTION_SEGMENT Segment
,
466 PLARGE_INTEGER ViewOffset
,
467 ULONG AllocationType
,
473 PHYSICAL_ADDRESS BoundaryAddressMultiple
;
475 BoundaryAddressMultiple
.QuadPart
= 0;
477 Status
= MmCreateMemoryArea
486 BoundaryAddressMultiple
);
488 if (!NT_SUCCESS(Status
))
490 DPRINT("Mapping between 0x%.8X and 0x%.8X failed (%X).\n",
491 (*BaseAddress
), (char*)(*BaseAddress
) + ViewSize
, Status
);
495 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
);
497 MArea
->Data
.CacheData
.Segment
= Segment
;
499 MArea
->Data
.CacheData
.ViewOffset
= *ViewOffset
;
501 MArea
->Data
.CacheData
.ViewOffset
.QuadPart
= 0;
504 MArea
->NotPresent
= MmNotPresentFaultPageFile
;
505 MArea
->AccessFault
= MiCowSectionPage
;
506 MArea
->PageOut
= MmPageOutPageFileView
;
510 ("MiMapViewOfSegment(P %x, A %x, T %x)\n",
511 MmGetAddressSpaceOwner(AddressSpace
), *BaseAddress
, MArea
->Type
);
513 return(STATUS_SUCCESS
);
519 (PMM_CACHE_SECTION_SEGMENT Segment
,
520 PLARGE_INTEGER FileOffset
)
523 PFILE_OBJECT FileObject
= Segment
->FileObject
;
525 Entry
= MiGetPageEntryCacheSectionSegment(Segment
, FileOffset
);
526 DPRINTC("MiFreeSegmentPage(%x:%08x%08x -> Entry %x\n",
527 Segment
, FileOffset
->HighPart
, FileOffset
->LowPart
, Entry
);
529 if (Entry
&& !IS_SWAP_FROM_SSE(Entry
))
531 // The segment is carrying a dirty page.
532 PFN_NUMBER OldPage
= PFN_FROM_SSE(Entry
);
533 if (IS_DIRTY_SSE(Entry
) && FileObject
)
535 DPRINT("MiWriteBackPage(%x,%wZ,%08x%08x)\n", Segment
, &FileObject
->FileName
, FileOffset
->u
.HighPart
, FileOffset
->u
.LowPart
);
536 MiWriteBackPage(FileObject
, FileOffset
, PAGE_SIZE
, OldPage
);
538 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");
540 MiSetPageEntryCacheSectionSegment(Segment
, FileOffset
, 0);
541 MmReleasePageMemoryConsumer(MC_CACHE
, OldPage
);
543 else if (IS_SWAP_FROM_SSE(Entry
))
545 DPRINT("Free swap\n");
546 MmFreeSwapPage(SWAPENTRY_FROM_SSE(Entry
));
553 MmFreeCacheSectionPage
554 (PVOID Context
, MEMORY_AREA
* MemoryArea
, PVOID Address
,
555 PFN_NUMBER Page
, SWAPENTRY SwapEntry
, BOOLEAN Dirty
)
558 PVOID
*ContextData
= Context
;
559 PMMSUPPORT AddressSpace
;
561 PMM_CACHE_SECTION_SEGMENT Segment
;
562 LARGE_INTEGER Offset
;
564 DPRINT("MmFreeSectionPage(%x,%x,%x,%x,%d)\n", MmGetAddressSpaceOwner(ContextData
[0]), Address
, Page
, SwapEntry
, Dirty
);
566 AddressSpace
= ContextData
[0];
567 Process
= MmGetAddressSpaceOwner(AddressSpace
);
568 Address
= (PVOID
)PAGE_ROUND_DOWN(Address
);
569 Segment
= ContextData
[1];
570 Offset
.QuadPart
= (ULONG_PTR
)Address
- (ULONG_PTR
)MemoryArea
->StartingAddress
+
571 MemoryArea
->Data
.CacheData
.ViewOffset
.QuadPart
;
573 Entry
= MiGetPageEntryCacheSectionSegment(Segment
, &Offset
);
577 DPRINT("Removing page %x:%x -> %x\n", Segment
, Offset
.LowPart
, Entry
);
578 MmSetSavedSwapEntryPage(Page
, 0);
579 MmDeleteRmap(Page
, Process
, Address
);
580 MmDeleteVirtualMapping(Process
, Address
, FALSE
, NULL
, NULL
);
581 MmReleasePageMemoryConsumer(MC_CACHE
, Page
);
583 if (Page
!= 0 && PFN_FROM_SSE(Entry
) == Page
&& Dirty
)
585 DPRINT("Freeing section page %x:%x -> %x\n", Segment
, Offset
.LowPart
, Entry
);
586 MiSetPageEntryCacheSectionSegment(Segment
, &Offset
, DIRTY_SSE(Entry
));
588 else if (SwapEntry
!= 0)
590 MmFreeSwapPage(SwapEntry
);
596 MmUnmapViewOfCacheSegment
597 (PMMSUPPORT AddressSpace
,
601 PMEMORY_AREA MemoryArea
;
602 PMM_CACHE_SECTION_SEGMENT Segment
;
604 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, BaseAddress
);
605 if (MemoryArea
== NULL
)
608 return(STATUS_UNSUCCESSFUL
);
611 MemoryArea
->DeleteInProgress
= TRUE
;
612 Segment
= MemoryArea
->Data
.CacheData
.Segment
;
613 MemoryArea
->Data
.CacheData
.Segment
= NULL
;
615 MmLockCacheSectionSegment(Segment
);
617 Context
[0] = AddressSpace
;
618 Context
[1] = Segment
;
619 DPRINT("MmFreeMemoryArea(%x,%x)\n", MmGetAddressSpaceOwner(AddressSpace
), MemoryArea
->StartingAddress
);
620 MmFreeMemoryArea(AddressSpace
, MemoryArea
, MmFreeCacheSectionPage
, Context
);
622 MmUnlockCacheSectionSegment(Segment
);
624 DPRINTC("MiUnmapViewOfSegment %x %x %x\n", MmGetAddressSpaceOwner(AddressSpace
), BaseAddress
, Segment
);
626 return(STATUS_SUCCESS
);
632 (PMM_CACHE_SECTION_SEGMENT Segment
,
633 PLARGE_INTEGER NewSize
,
636 LARGE_INTEGER OldSize
;
637 DPRINT("Extend Segment %x\n", Segment
);
639 MmLockCacheSectionSegment(Segment
);
640 OldSize
.QuadPart
= Segment
->RawLength
.QuadPart
;
641 MmUnlockCacheSectionSegment(Segment
);
643 DPRINT("OldSize %08x%08x NewSize %08x%08x\n",
644 OldSize
.u
.HighPart
, OldSize
.u
.LowPart
,
645 NewSize
->u
.HighPart
, NewSize
->u
.LowPart
);
647 if (ExtendFile
&& OldSize
.QuadPart
< NewSize
->QuadPart
)
650 Status
= IoSetInformation(Segment
->FileObject
, FileEndOfFileInformation
, sizeof(LARGE_INTEGER
), NewSize
);
651 if (!NT_SUCCESS(Status
)) return Status
;
654 MmLockCacheSectionSegment(Segment
);
655 Segment
->RawLength
.QuadPart
= NewSize
->QuadPart
;
656 Segment
->Length
.QuadPart
= MAX(Segment
->Length
.QuadPart
, PAGE_ROUND_UP(Segment
->RawLength
.LowPart
));
657 MmUnlockCacheSectionSegment(Segment
);
658 return STATUS_SUCCESS
;
663 MmMapCacheViewInSystemSpaceAtOffset
664 (IN PMM_CACHE_SECTION_SEGMENT Segment
,
665 OUT PVOID
*MappedBase
,
666 PLARGE_INTEGER FileOffset
,
667 IN OUT PULONG ViewSize
)
669 PMMSUPPORT AddressSpace
;
672 DPRINT("MmMapViewInSystemSpaceAtOffset() called offset %08x%08x\n", FileOffset
->HighPart
, FileOffset
->LowPart
);
674 AddressSpace
= MmGetKernelAddressSpace();
676 MmLockAddressSpace(AddressSpace
);
677 MmLockCacheSectionSegment(Segment
);
679 Status
= MiMapViewOfSegment
688 MmUnlockCacheSectionSegment(Segment
);
689 MmUnlockAddressSpace(AddressSpace
);
698 MmUnmapCacheViewInSystemSpace (IN PVOID MappedBase
)
700 PMMSUPPORT AddressSpace
;
703 DPRINT("MmUnmapViewInSystemSpace() called\n");
705 AddressSpace
= MmGetKernelAddressSpace();
707 Status
= MmUnmapViewOfCacheSegment(AddressSpace
, MappedBase
);