56#undef MmSetPageEntrySectionSegment
57#define MmSetPageEntrySectionSegment(S,O,E) do { \
58 DPRINT("SetPageEntrySectionSegment(old,%p,%x,%x)\n",(S),(O)->LowPart,E); \
59 _MmSetPageEntrySectionSegment((S),(O),(E),__FILE__,__LINE__); \
295 ULONG cbFileHeaderOffsetSize = 0;
296 ULONG cbSectionHeadersOffset = 0;
297 ULONG cbSectionHeadersSize;
298 ULONG cbSectionHeadersOffsetSize = 0;
299 ULONG cbOptHeaderSize;
300 ULONG cbHeadersSize = 0;
301 ULONG nSectionAlignment;
302 ULONG nFileAlignment;
311 SIZE_T nPrevVirtualEndOfSegment = 0;
312 ULONG nFileSizeOfHeaders = 0;
317 ASSERT(FileHeaderSize > 0);
319 ASSERT(ImageSectionObject);
321 ASSERT(AllocateSegmentsCb);
327#define DIE(ARGS_) { DPRINT ARGS_; goto l_Return; }
330 pidhDosHeader = FileHeader;
337 DIE((
"Too small to be an MZ executable, size is %lu\n", FileHeaderSize));
341 DIE((
"No MZ signature found, e_magic is %hX\n", pidhDosHeader->
e_magic));
348 DIE((
"Not a Windows executable, e_lfanew is %d\n", pidhDosHeader->
e_lfanew));
351 DIE((
"The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->
e_lfanew));
353 if(FileHeaderSize < cbFileHeaderOffsetSize)
369 if(FileHeaderSize < cbFileHeaderOffsetSize ||
372 ULONG cbNtHeaderSize;
390 DIE((
"ReadFile failed, status %08X\n", ReturnedStatus));
401 DIE((
"The file doesn't contain the PE file header\n"));
403 pinhNtHeader =
pData;
417 DIE((
"The file isn't a PE executable, Signature is %X\n", pinhNtHeader->
Signature));
422 DIE((
"The full NT header is too large\n"));
425 if(cbReadSize < cbNtHeaderSize)
426 DIE((
"The file doesn't contain the full NT header\n"));
430 ULONG cbOptHeaderOffsetSize = 0;
436 DIE((
"The file isn't a PE executable, Signature is %X\n", pinhNtHeader->
Signature));
439 DIE((
"The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->
e_lfanew));
447 if(cbOptHeaderOffsetSize > FileHeaderSize)
448 goto l_ReadHeaderFromFile;
458 DIE((
"The optional header doesn't contain the Magic field, SizeOfOptionalHeader is %X\n", cbOptHeaderSize));
462 switch(piohOptHeader->
Magic)
467 DIE((
"Win64 optional header, unsupported\n"));
474 DIE((
"Unrecognized optional header, Magic is %X\n", piohOptHeader->
Magic));
484 DIE((
"Sections aren't page-aligned and the file alignment isn't the same\n"));
487 DIE((
"The section alignment is smaller than the file alignment\n"));
493 DIE((
"The section alignment (%u) and file alignment (%u) aren't both powers of 2\n", nSectionAlignment, nFileAlignment));
504 switch(piohOptHeader->
Magic)
513 ImageSectionObject->ImageInformation.ImageFileSize = piohOptHeader->
SizeOfImage;
516 ImageSectionObject->ImageInformation.MaximumStackSize = piohOptHeader->
SizeOfStackReserve;
519 ImageSectionObject->ImageInformation.CommittedStackSize = piohOptHeader->
SizeOfStackCommit;
523 ImageSectionObject->ImageInformation.SubSystemType = piohOptHeader->
Subsystem;
535 ImageSectionObject->ImageInformation.TransferAddress = (
PVOID) (ImageBase +
540 ImageSectionObject->ImageInformation.ImageContainsCode = piohOptHeader->
SizeOfCode != 0;
542 ImageSectionObject->ImageInformation.ImageContainsCode =
TRUE;
548 ImageSectionObject->ImageInformation.ImageContainsCode =
FALSE;
553 ImageSectionObject->ImageInformation.LoaderFlags = piohOptHeader->
LoaderFlags;
557 ImageSectionObject->ImageInformation.DllCharacteristics = piohOptHeader->
DllCharacteristics;
587 DIE((
"ImageBase exceeds the address space\n"));
593 DIE((
"SizeOfImage exceeds the address space\n"));
595 ImageSectionObject->ImageInformation.ImageFileSize = pioh64OptHeader->
SizeOfImage;
601 DIE((
"SizeOfStackReserve exceeds the address space\n"));
609 DIE((
"SizeOfStackCommit exceeds the address space\n"));
616 ImageSectionObject->ImageInformation.SubSystemType = pioh64OptHeader->
Subsystem;
628 ImageSectionObject->ImageInformation.TransferAddress = (
PVOID) (ImageBase +
633 ImageSectionObject->ImageInformation.ImageContainsCode = pioh64OptHeader->
SizeOfCode != 0;
635 ImageSectionObject->ImageInformation.ImageContainsCode =
TRUE;
641 ImageSectionObject->ImageInformation.ImageContainsCode =
FALSE;
646 ImageSectionObject->ImageInformation.LoaderFlags = pioh64OptHeader->
LoaderFlags;
649 ImageSectionObject->ImageInformation.DllCharacteristics = pioh64OptHeader->
DllCharacteristics;
658 DIE((
"ImageBase is not aligned on a 64KB boundary"));
662 ImageSectionObject->ImageInformation.GpValue = 0;
663 ImageSectionObject->ImageInformation.ZeroBits = 0;
664 ImageSectionObject->BasedAddress = (
PVOID)ImageBase;
682 DIE((
"Offset overflow\n"));
685 DIE((
"Offset overflow\n"));
691 if(!
Intsafe_AddULong32(&cbSectionHeadersOffsetSize, cbSectionHeadersOffset, cbSectionHeadersSize))
692 DIE((
"Section headers too large\n"));
701 DIE((
"The section headers overflow SizeOfHeaders\n"));
705 else if(!
AlignUp(&cbHeadersSize, cbSectionHeadersOffsetSize, nFileAlignment))
706 DIE((
"Overflow aligning the size of headers\n"));
717 if(FileHeaderSize < cbSectionHeadersOffsetSize)
718 pishSectionHeaders =
NULL;
726 pishSectionHeaders = (
PVOID)((
UINT_PTR)FileHeader + cbSectionHeadersOffset);
733 if(FileHeaderSize < cbSectionHeadersOffsetSize ||
739 lnOffset.
QuadPart = cbSectionHeadersOffset;
742 nStatus = ReadFileCb(
File, &lnOffset, cbSectionHeadersSize, &
pData, &
pBuffer, &cbReadSize);
745 DIE((
"ReadFile failed with status %08X\n", nStatus));
754 if(cbReadSize < cbSectionHeadersSize)
755 DIE((
"The file doesn't contain all of the section headers\n"));
757 pishSectionHeaders =
pData;
771 ImageSectionObject->Segments = AllocateSegmentsCb(ImageSectionObject->NrSegments);
773 if(ImageSectionObject->Segments ==
NULL)
774 DIE((
"AllocateSegments failed\n"));
777 pssSegments = ImageSectionObject->Segments;
781 if(!
AlignUp(&nFileSizeOfHeaders, cbHeadersSize, nFileAlignment))
782 DIE((
"Cannot align the size of the section headers\n"));
784 nPrevVirtualEndOfSegment =
ALIGN_UP_BY(cbHeadersSize, nSectionAlignment);
785 if (nPrevVirtualEndOfSegment < cbHeadersSize)
786 DIE((
"Cannot align the size of the section headers\n"));
788 pssSegments[0].
Image.FileOffset = 0;
792 pssSegments[0].
Image.VirtualAddress = 0;
793 pssSegments[0].
Image.Characteristics = 0;
801 ASSERT(ImageSectionObject->RefCount > 0);
804 for(
i = 0;
i < ImageSectionObject->NrSegments - 1; ++
i)
806 ULONG nCharacteristics;
810 DIE((
"Image.VirtualAddress[%u] is not aligned\n",
i));
814 DIE((
"Memory gap between section %u and the previous\n",
i));
817 if(pishSectionHeaders[
i].PointerToRawData != 0 && pishSectionHeaders[
i].SizeOfRawData != 0)
824 if(!
IsAligned(pishSectionHeaders[
i].SizeOfRawData, nFileAlignment))
825 DIE((
"SizeOfRawData[%u] is not aligned\n",
i));
832 DIE((
"SizeOfRawData[%u] too large\n",
i));
842 ASSERT(pssSegments[
i].RawLength.QuadPart == 0);
872 if(AlignedLength < pssSegments[
i].
Length.LowPart)
873 DIE((
"Cannot align the virtual size of section %u\n",
i));
877 if(pssSegments[
i].
Length.QuadPart == 0)
878 DIE((
"Virtual size of section %u is null\n",
i));
885 if (nPrevVirtualEndOfSegment < pssSegments[
i].
Image.VirtualAddress)
886 DIE((
"The image is too large\n"));
945 if (SavedSwapEntry != 0)
996MmDereferenceSegmentWithLock(
1025 Segment->FileObject->SectionObjectPointer->DataSectionObject =
NULL;
1040 ASSERT(ImageSectionObject->
FileObject->SectionObjectPointer->ImageSectionObject == ImageSectionObject);
1041 ImageSectionObject->
FileObject->SectionObjectPointer->ImageSectionObject =
NULL;
1047 SectionSegments = ImageSectionObject->
Segments;
1048 for (
i = 0;
i < NrSegments;
i++)
1073 DPRINT1(
"Entry == 0 for MmSharePageEntrySectionSegment\n");
1078 DPRINT1(
"Maximum share count reached\n");
1104 DPRINT1(
"Entry == 0 for MmUnsharePageEntrySectionSegment\n");
1179 if (DestAddress ==
NULL)
1217 if (RangeEnd %
_64K)
1218 RangeEnd +=
_64K - (RangeEnd %
_64K);
1230 if (RangeEnd >
Segment->RawLength.QuadPart)
1231 RangeEnd =
Segment->RawLength.QuadPart;
1235 for ( ; RangeStart < RangeEnd; RangeStart +=
_64K)
1238 ULONG ToReadPageBits = 0;
1241 if (ChunkEnd > RangeEnd)
1242 ChunkEnd = RangeEnd;
1245 for (
LONGLONG ChunkOffset = RangeStart; ChunkOffset < ChunkEnd; ChunkOffset +=
PAGE_SIZE)
1249 CurrentOffset.
QuadPart = ChunkOffset;
1271 ToReadPageBits |= 1UL << ((ChunkOffset - RangeStart) >>
PAGE_SHIFT);
1278 if (ToReadPageBits == 0)
1286 while (ChunkOffset < ChunkEnd)
1295 ToReadPageBits >>= BitSet;
1297 ASSERT(ChunkOffset < ChunkEnd);
1317 while (ChunkOffset < ChunkEnd)
1319 if (ToReadPageBits & 1)
1322 CurrentOffset.
QuadPart = ChunkOffset;
1326 ToReadPageBits >>= 1;
1349 if (
FileOffset.QuadPart > ValidDataLength->QuadPart)
1352 goto AssignPagesToSegment;
1393 while (ChunkOffset < ChunkEnd)
1395 if (ToReadPageBits & 1)
1398 CurrentOffset.
QuadPart = ChunkOffset;
1402 ToReadPageBits >>= 1;
1410AssignPagesToSegment:
1430 ToReadPageBits >>= BitSet;
1476 if (SwapEntry != MM_WAIT_ENTRY)
1594 DPRINT1(
"Removing PAGE_GUARD protection failed : 0x%08x.\n",
Status);
1608 if (SwapEntry == MM_WAIT_ENTRY)
1624 ASSERT(DummyEntry == SwapEntry);
1642 DPRINT1(
"MmReadFromSwapPage failed, status = %x\n",
Status);
1648 ASSERT(DummyEntry == MM_WAIT_ENTRY);
1656 DPRINT(
"MmCreateVirtualMapping failed, not out of memory\n");
1698 DPRINT(
"MmCreateVirtualMappingUnsafe failed, not out of memory\n");
1746 DPRINT1(
"Unable to create virtual mapping\n");
1774 DPRINT1(
"Failed to page data in!\n");
1788 if (SwapEntry == MM_WAIT_ENTRY)
1829 DPRINT1(
"Someone changed ppte entry while we slept (%x vs %x)\n",
Entry, Entry1);
1845 DPRINT1(
"Unable to create virtual mapping\n");
1873 DPRINT1(
"Unable to create virtual mapping\n");
2006 DPRINT(
"Swapping page (Old %x New %x)\n", OldPage, NewPage);
2008 if (!Unmapped || (UnmappedPage != OldPage))
2028 DPRINT1(
"MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
2067 *OldProtect =
Region->Protect;
2083 PVOID RegionBaseAddress;
2105 Info->BaseAddress = RegionBaseAddress;
2127 DPRINT(
"MmpDeleteSection(ObjectBody %p)\n", ObjectBody);
2208 sizeof(*PhysSection),
2211 (
PVOID*)&PhysSection);
2214 DPRINT1(
"MmCreatePhysicalMemorySection: failed to create object (0x%lx)\n",
Status);
2243 Segment->Image.FileOffset = 0;
2245 Segment->RawLength = SectionSize;
2246 Segment->Length = SectionSize;
2249 Segment->Image.VirtualAddress = 0;
2250 Segment->Image.Characteristics = 0;
2277 DPRINT(
"Creating Section Object Type\n");
2284 RtlZeroMemory(&ObjectTypeInitializer,
sizeof(ObjectTypeInitializer));
2286 ObjectTypeInitializer.
Length =
sizeof(ObjectTypeInitializer);
2374 if ((UMaximumSize !=
NULL) && (UMaximumSize->
QuadPart != 0))
2483 Segment->Image.FileOffset = 0;
2486 Segment->Image.Characteristics = 0;
2497 Segment->Image.VirtualAddress = 0;
2502 Segment->SegFlags &= ~MM_SEGMENT_INCREATE;
2598 ULONG OffsetAdjustment;
2621 OffsetAdjustment =
FileOffset.u.LowPart - AdjustOffset;
2653 *ReadSize = UsedSize - OffsetAdjustment;
2664# define MmspAssertSegmentsSorted(OBJ_) ((void)0)
2665# define MmspAssertSegmentsNoOverlap(OBJ_) ((void)0)
2666# define MmspAssertSegmentsPageAligned(OBJ_) ((void)0)
2675 for(
i = 1;
i < ImageSectionObject->NrSegments; ++
i )
2677 ASSERT(ImageSectionObject->Segments[
i].Image.VirtualAddress >=
2678 ImageSectionObject->Segments[
i - 1].Image.VirtualAddress);
2691 for(
i = 0;
i < ImageSectionObject->NrSegments; ++
i )
2693 ASSERT(ImageSectionObject->Segments[
i].Length.QuadPart > 0);
2697 ASSERT(ImageSectionObject->Segments[
i].Image.VirtualAddress >=
2698 (ImageSectionObject->Segments[
i - 1].Image.VirtualAddress +
2699 ImageSectionObject->Segments[
i - 1].Length.QuadPart));
2711 for(
i = 0;
i < ImageSectionObject->NrSegments; ++
i )
2713 ASSERT((ImageSectionObject->Segments[
i].Image.VirtualAddress %
PAGE_SIZE) == 0);
2714 ASSERT((ImageSectionObject->Segments[
i].Length.QuadPart %
PAGE_SIZE) == 0);
2728 if (Segment1->
Image.VirtualAddress > Segment2->
Image.VirtualAddress)
2730 else if (Segment1->
Image.VirtualAddress < Segment2->
Image.VirtualAddress)
2751 qsort(ImageSectionObject->Segments,
2752 ImageSectionObject->NrSegments,
2753 sizeof(ImageSectionObject->Segments[0]),
2781 ASSERT(ImageSectionObject->NrSegments >= 1);
2783 for (
i = 0;
i < ImageSectionObject->NrSegments; ++
i )
2785 if(ImageSectionObject->Segments[
i].Length.QuadPart == 0)
2799 if ((ImageSectionObject->Segments[
i - 1].Image.VirtualAddress +
2800 ImageSectionObject->Segments[
i - 1].Length.QuadPart) !=
2801 ImageSectionObject->Segments[
i].Image.VirtualAddress)
2835 EffectiveSegment = &ImageSectionObject->Segments[LastSegment];
2837 for (
i = 0;
i < ImageSectionObject->NrSegments; ++
i )
2854 EffectiveSegment->
Image.VirtualAddress;
2859 if (EffectiveSegment->
Image.FileOffset < VirtualOffset)
2869 EffectiveSegment->
Image.FileOffset -= VirtualOffset;
2884 if (EndOfEffectiveSegment ==
Segment->Image.VirtualAddress)
2888 ASSERT(LastSegment < ImageSectionObject->NrSegments);
2890 EffectiveSegment = &ImageSectionObject->Segments[LastSegment];
2892 if (LastSegment !=
i)
2912 else if (EndOfEffectiveSegment >
Segment->Image.VirtualAddress)
2914 static const ULONG FlagsToProtection[16] =
2934 unsigned ProtectionFlags;
2941 if (
Segment->Image.FileOffset != (EffectiveSegment->
Image.FileOffset +
2955 EffectiveSegment->
Image.VirtualAddress;
2963 ProtectionFlags = 0;
2966 ProtectionFlags |= 1 << 0;
2969 ProtectionFlags |= 1 << 1;
2972 ProtectionFlags |= 1 << 2;
2975 ProtectionFlags |= 1 << 3;
2977 ASSERT(ProtectionFlags < 16);
2978 EffectiveSegment->
Protection = FlagsToProtection[ProtectionFlags];
2996 ImageSectionObject->NrSegments = LastSegment + 1;
3007 PVOID FileHeaderBuffer;
3008 ULONG FileHeaderSize;
3010 ULONG OldNrSegments;
3030 if (FileHeaderSize == 0)
3053 if (ImageSectionObject->Segments)
3056 ImageSectionObject->Segments =
NULL;
3111 OldNrSegments = ImageSectionObject->
NrSegments;
3117 if (ImageSectionObject->
NrSegments < OldNrSegments)
3128 if (Segments ==
NULL)
3133 ImageSectionObject->
Segments = Segments;
3174 DPRINT1(
"Denying section creation due to missing cache initialization\n");
3209grab_image_section_object:
3213 ImageSectionObject =
FileObject->SectionObjectPointer->ImageSectionObject;
3221 ImageSectionObject =
FileObject->SectionObjectPointer->ImageSectionObject;
3224 if (ImageSectionObject ==
NULL)
3232 if (ImageSectionObject ==
NULL)
3243 if (
FileObject->SectionObjectPointer->ImageSectionObject !=
NULL)
3248 goto grab_image_section_object;
3251 FileObject->SectionObjectPointer->ImageSectionObject = ImageSectionObject;
3306 ImageSectionObject->
SegFlags &= ~MM_SEGMENT_INCREATE;
3318 ImageSectionObject->
SegFlags &= ~MM_IMAGE_SECTION_FLUSH_DELETE;
3397 DPRINT1(
"Mapping between 0x%p and 0x%p failed (%X).\n",
3481 if (SavedSwapEntry != 0)
3560 MmDereferenceSegment(
Segment);
3574 PVOID ImageBaseAddress = 0;
3576 DPRINT(
"Opening memory area Process %p BaseAddress %p\n",
3610 SectionSegments = ImageSectionObject->
Segments;
3617 for (
i = 0;
i < NrSegments;
i++)
3619 if (
Segment == &SectionSegments[
i])
3625 if (
i >= NrSegments)
3630 for (
i = 0;
i < NrSegments;
i++)
3633 ((
char*)ImageBaseAddress + (
ULONG_PTR)SectionSegments[
i].
Image.VirtualAddress);
3638 DPRINT1(
"MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3643 DPRINT(
"One mapping less for %p\n", ImageSectionObject->
FileObject->SectionObjectPointer);
3660 DPRINT1(
"MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3668 MmDereferenceSegment(
Segment);
3680 MmDereferenceSegment(
Segment);
3704 MmDereferenceSegment(
Segment);
3758 SectionInformationLength,
3805 switch(SectionInformationClass)
3848 DPRINT1(
"Unimplemented code path!");
3909 DPRINT1(
"Unknown SectionInformationClass: %d\n", SectionInformationClass);
3986 DPRINT(
"Mapping ARM3 section into %s\n",
Process->ImageFileName);
4027 SectionSegments = ImageSectionObject->
Segments;
4039 for (
i = 0;
i < NrSegments;
i++)
4044 ImageSize =
max(ImageSize, MaxExtent);
4051 ((ImageBase + ImageSize) < ImageSize))
4086 for (
i = 0;
i < NrSegments;
i++)
4089 ((
char*)ImageBase + (
ULONG_PTR)SectionSegments[
i].
Image.VirtualAddress);
4093 &SectionSegments[
i],
4095 SectionSegments[
i].
Length.QuadPart,
4105 SBaseAddress = ((
char*)ImageBase + (
ULONG_PTR)SectionSegments[
i].
Image.VirtualAddress);
4119 DPRINT(
"Mapped %p for section pointer %p\n", ImageSectionObject, ImageSectionObject->
FileObject->SectionObjectPointer);
4224 DPRINT1(
"ERROR: File can't be truncated because it has an image section\n");
4236 if ((
Segment->SectionCount == 0) ||
4255 DPRINT1(
"ERROR: File can't be truncated because it has references held to its data section\n");
4260 MmDereferenceSegment(
Segment);
4262 DPRINT(
"FIXME: didn't check for outstanding write probes\n");
4320 case MmFlushForDelete:
4328 case MmFlushForWrite:
4345 if (!ImageSectionObject)
4347 DPRINT(
"No image section object. Accepting\n");
4358 DPRINT(
"Denying. There are mappings open\n");