55#undef MmSetPageEntrySectionSegment
56#define MmSetPageEntrySectionSegment(S,O,E) do { \
57 DPRINT("SetPageEntrySectionSegment(old,%p,%x,%x)\n",(S),(O)->LowPart,E); \
58 _MmSetPageEntrySectionSegment((S),(O),(E),__FILE__,__LINE__); \
294 ULONG cbFileHeaderOffsetSize = 0;
295 ULONG cbSectionHeadersOffset = 0;
296 ULONG cbSectionHeadersSize;
297 ULONG cbSectionHeadersOffsetSize = 0;
298 ULONG cbOptHeaderSize;
299 ULONG cbHeadersSize = 0;
300 ULONG nSectionAlignment;
301 ULONG nFileAlignment;
310 SIZE_T nPrevVirtualEndOfSegment = 0;
311 ULONG nFileSizeOfHeaders = 0;
316 ASSERT(FileHeaderSize > 0);
318 ASSERT(ImageSectionObject);
320 ASSERT(AllocateSegmentsCb);
326#define DIE(ARGS_) { DPRINT ARGS_; goto l_Return; }
329 pidhDosHeader = FileHeader;
336 DIE((
"Too small to be an MZ executable, size is %lu\n", FileHeaderSize));
340 DIE((
"No MZ signature found, e_magic is %hX\n", pidhDosHeader->
e_magic));
347 DIE((
"Not a Windows executable, e_lfanew is %d\n", pidhDosHeader->
e_lfanew));
350 DIE((
"The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->
e_lfanew));
352 if(FileHeaderSize < cbFileHeaderOffsetSize)
368 if(FileHeaderSize < cbFileHeaderOffsetSize ||
371 ULONG cbNtHeaderSize;
389 DIE((
"ReadFile failed, status %08X\n", ReturnedStatus));
400 DIE((
"The file doesn't contain the PE file header\n"));
402 pinhNtHeader =
pData;
416 DIE((
"The file isn't a PE executable, Signature is %X\n", pinhNtHeader->
Signature));
421 DIE((
"The full NT header is too large\n"));
424 if(cbReadSize < cbNtHeaderSize)
425 DIE((
"The file doesn't contain the full NT header\n"));
429 ULONG cbOptHeaderOffsetSize = 0;
435 DIE((
"The file isn't a PE executable, Signature is %X\n", pinhNtHeader->
Signature));
438 DIE((
"The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->
e_lfanew));
446 if(cbOptHeaderOffsetSize > FileHeaderSize)
447 goto l_ReadHeaderFromFile;
457 DIE((
"The optional header doesn't contain the Magic field, SizeOfOptionalHeader is %X\n", cbOptHeaderSize));
461 switch(piohOptHeader->
Magic)
466 DIE((
"Win64 optional header, unsupported\n"));
473 DIE((
"Unrecognized optional header, Magic is %X\n", piohOptHeader->
Magic));
483 DIE((
"Sections aren't page-aligned and the file alignment isn't the same\n"));
486 DIE((
"The section alignment is smaller than the file alignment\n"));
492 DIE((
"The section alignment (%u) and file alignment (%u) aren't both powers of 2\n", nSectionAlignment, nFileAlignment));
503 switch(piohOptHeader->
Magic)
512 ImageSectionObject->ImageInformation.ImageFileSize = piohOptHeader->
SizeOfImage;
515 ImageSectionObject->ImageInformation.MaximumStackSize = piohOptHeader->
SizeOfStackReserve;
518 ImageSectionObject->ImageInformation.CommittedStackSize = piohOptHeader->
SizeOfStackCommit;
522 ImageSectionObject->ImageInformation.SubSystemType = piohOptHeader->
Subsystem;
534 ImageSectionObject->ImageInformation.TransferAddress = (
PVOID) (ImageBase +
539 ImageSectionObject->ImageInformation.ImageContainsCode = piohOptHeader->
SizeOfCode != 0;
541 ImageSectionObject->ImageInformation.ImageContainsCode =
TRUE;
547 ImageSectionObject->ImageInformation.ImageContainsCode =
FALSE;
552 ImageSectionObject->ImageInformation.LoaderFlags = piohOptHeader->
LoaderFlags;
556 ImageSectionObject->ImageInformation.DllCharacteristics = piohOptHeader->
DllCharacteristics;
586 DIE((
"ImageBase exceeds the address space\n"));
592 DIE((
"SizeOfImage exceeds the address space\n"));
594 ImageSectionObject->ImageInformation.ImageFileSize = pioh64OptHeader->
SizeOfImage;
600 DIE((
"SizeOfStackReserve exceeds the address space\n"));
608 DIE((
"SizeOfStackCommit exceeds the address space\n"));
615 ImageSectionObject->ImageInformation.SubSystemType = pioh64OptHeader->
Subsystem;
627 ImageSectionObject->ImageInformation.TransferAddress = (
PVOID) (ImageBase +
632 ImageSectionObject->ImageInformation.ImageContainsCode = pioh64OptHeader->
SizeOfCode != 0;
634 ImageSectionObject->ImageInformation.ImageContainsCode =
TRUE;
640 ImageSectionObject->ImageInformation.ImageContainsCode =
FALSE;
645 ImageSectionObject->ImageInformation.LoaderFlags = pioh64OptHeader->
LoaderFlags;
648 ImageSectionObject->ImageInformation.DllCharacteristics = pioh64OptHeader->
DllCharacteristics;
657 DIE((
"ImageBase is not aligned on a 64KB boundary"));
661 ImageSectionObject->ImageInformation.GpValue = 0;
662 ImageSectionObject->ImageInformation.ZeroBits = 0;
663 ImageSectionObject->BasedAddress = (
PVOID)ImageBase;
681 DIE((
"Offset overflow\n"));
684 DIE((
"Offset overflow\n"));
690 if(!
Intsafe_AddULong32(&cbSectionHeadersOffsetSize, cbSectionHeadersOffset, cbSectionHeadersSize))
691 DIE((
"Section headers too large\n"));
700 DIE((
"The section headers overflow SizeOfHeaders\n"));
704 else if(!
AlignUp(&cbHeadersSize, cbSectionHeadersOffsetSize, nFileAlignment))
705 DIE((
"Overflow aligning the size of headers\n"));
716 if(FileHeaderSize < cbSectionHeadersOffsetSize)
717 pishSectionHeaders =
NULL;
725 pishSectionHeaders = (
PVOID)((
UINT_PTR)FileHeader + cbSectionHeadersOffset);
732 if(FileHeaderSize < cbSectionHeadersOffsetSize ||
738 lnOffset.
QuadPart = cbSectionHeadersOffset;
741 nStatus = ReadFileCb(
File, &lnOffset, cbSectionHeadersSize, &
pData, &
pBuffer, &cbReadSize);
744 DIE((
"ReadFile failed with status %08X\n", nStatus));
753 if(cbReadSize < cbSectionHeadersSize)
754 DIE((
"The file doesn't contain all of the section headers\n"));
756 pishSectionHeaders =
pData;
770 ImageSectionObject->Segments = AllocateSegmentsCb(ImageSectionObject->NrSegments);
772 if(ImageSectionObject->Segments ==
NULL)
773 DIE((
"AllocateSegments failed\n"));
776 pssSegments = ImageSectionObject->Segments;
780 if(!
AlignUp(&nFileSizeOfHeaders, cbHeadersSize, nFileAlignment))
781 DIE((
"Cannot align the size of the section headers\n"));
783 nPrevVirtualEndOfSegment =
ALIGN_UP_BY(cbHeadersSize, nSectionAlignment);
784 if (nPrevVirtualEndOfSegment < cbHeadersSize)
785 DIE((
"Cannot align the size of the section headers\n"));
787 pssSegments[0].
Image.FileOffset = 0;
791 pssSegments[0].
Image.VirtualAddress = 0;
792 pssSegments[0].
Image.Characteristics = 0;
800 ASSERT(ImageSectionObject->RefCount > 0);
803 for(
i = 0;
i < ImageSectionObject->NrSegments - 1; ++
i)
805 ULONG nCharacteristics;
809 DIE((
"Image.VirtualAddress[%u] is not aligned\n",
i));
813 DIE((
"Memory gap between section %u and the previous\n",
i));
816 if(pishSectionHeaders[
i].PointerToRawData != 0 && pishSectionHeaders[
i].SizeOfRawData != 0)
823 if(!
IsAligned(pishSectionHeaders[
i].SizeOfRawData, nFileAlignment))
824 DIE((
"SizeOfRawData[%u] is not aligned\n",
i));
831 DIE((
"SizeOfRawData[%u] too large\n",
i));
841 ASSERT(pssSegments[
i].RawLength.QuadPart == 0);
871 if(AlignedLength < pssSegments[
i].
Length.LowPart)
872 DIE((
"Cannot align the virtual size of section %u\n",
i));
876 if(pssSegments[
i].
Length.QuadPart == 0)
877 DIE((
"Virtual size of section %u is null\n",
i));
884 if (nPrevVirtualEndOfSegment < pssSegments[
i].
Image.VirtualAddress)
885 DIE((
"The image is too large\n"));
944 if (SavedSwapEntry != 0)
995MmDereferenceSegmentWithLock(
1024 Segment->FileObject->SectionObjectPointer->DataSectionObject =
NULL;
1039 ASSERT(ImageSectionObject->
FileObject->SectionObjectPointer->ImageSectionObject == ImageSectionObject);
1040 ImageSectionObject->
FileObject->SectionObjectPointer->ImageSectionObject =
NULL;
1046 SectionSegments = ImageSectionObject->
Segments;
1047 for (
i = 0;
i < NrSegments;
i++)
1072 DPRINT1(
"Entry == 0 for MmSharePageEntrySectionSegment\n");
1077 DPRINT1(
"Maximum share count reached\n");
1103 DPRINT1(
"Entry == 0 for MmUnsharePageEntrySectionSegment\n");
1178 if (DestAddress ==
NULL)
1216 if (RangeEnd %
_64K)
1217 RangeEnd +=
_64K - (RangeEnd %
_64K);
1229 if (RangeEnd >
Segment->RawLength.QuadPart)
1230 RangeEnd =
Segment->RawLength.QuadPart;
1234 for ( ; RangeStart < RangeEnd; RangeStart +=
_64K)
1237 ULONG ToReadPageBits = 0;
1240 if (ChunkEnd > RangeEnd)
1241 ChunkEnd = RangeEnd;
1244 for (
LONGLONG ChunkOffset = RangeStart; ChunkOffset < ChunkEnd; ChunkOffset +=
PAGE_SIZE)
1248 CurrentOffset.
QuadPart = ChunkOffset;
1270 ToReadPageBits |= 1UL << ((ChunkOffset - RangeStart) >>
PAGE_SHIFT);
1277 if (ToReadPageBits == 0)
1285 while (ChunkOffset < ChunkEnd)
1294 ToReadPageBits >>= BitSet;
1296 ASSERT(ChunkOffset < ChunkEnd);
1316 while (ChunkOffset < ChunkEnd)
1318 if (ToReadPageBits & 1)
1321 CurrentOffset.
QuadPart = ChunkOffset;
1325 ToReadPageBits >>= 1;
1355 if (
FileOffset.QuadPart > ValidDataLength->QuadPart)
1358 goto AssignPagesToSegment;
1400 while (ChunkOffset < ChunkEnd)
1402 if (ToReadPageBits & 1)
1405 CurrentOffset.
QuadPart = ChunkOffset;
1409 ToReadPageBits >>= 1;
1417AssignPagesToSegment:
1437 ToReadPageBits >>= BitSet;
1483 if (SwapEntry != MM_WAIT_ENTRY)
1606 DPRINT1(
"Removing PAGE_GUARD protection failed : 0x%08x.\n",
Status);
1620 if (SwapEntry == MM_WAIT_ENTRY)
1645 ASSERT(DummyEntry == SwapEntry);
1655 DPRINT1(
"MmReadFromSwapPage failed, status = %x\n",
Status);
1661 ASSERT(DummyEntry == MM_WAIT_ENTRY);
1669 DPRINT(
"MmCreateVirtualMapping failed, not out of memory\n");
1711 DPRINT(
"MmCreateVirtualMappingUnsafe failed, not out of memory\n");
1764 DPRINT1(
"Unable to create virtual mapping\n");
1796 DPRINT1(
"Failed to page data in!\n");
1810 if (SwapEntry == MM_WAIT_ENTRY)
1853 DPRINT1(
"Someone changed ppte entry while we slept (%x vs %x)\n",
Entry, Entry1);
1869 DPRINT1(
"Unable to create virtual mapping\n");
1897 DPRINT1(
"Unable to create virtual mapping\n");
2033 DPRINT(
"Swapping page (Old %x New %x)\n", OldPage, NewPage);
2035 if (!Unmapped || (UnmappedPage != OldPage))
2055 DPRINT1(
"MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
2094 *OldProtect =
Region->Protect;
2110 PVOID RegionBaseAddress;
2132 Info->BaseAddress = RegionBaseAddress;
2154 DPRINT(
"MmpDeleteSection(ObjectBody %p)\n", ObjectBody);
2235 sizeof(*PhysSection),
2238 (
PVOID*)&PhysSection);
2241 DPRINT1(
"MmCreatePhysicalMemorySection: failed to create object (0x%lx)\n",
Status);
2270 Segment->Image.FileOffset = 0;
2272 Segment->RawLength = SectionSize;
2273 Segment->Length = SectionSize;
2276 Segment->Image.VirtualAddress = 0;
2277 Segment->Image.Characteristics = 0;
2304 DPRINT(
"Creating Section Object Type\n");
2311 RtlZeroMemory(&ObjectTypeInitializer,
sizeof(ObjectTypeInitializer));
2313 ObjectTypeInitializer.
Length =
sizeof(ObjectTypeInitializer);
2401 if ((UMaximumSize !=
NULL) && (UMaximumSize->
QuadPart != 0))
2510 Segment->Image.FileOffset = 0;
2513 Segment->Image.Characteristics = 0;
2524 Segment->Image.VirtualAddress = 0;
2529 Segment->SegFlags &= ~MM_SEGMENT_INCREATE;
2625 ULONG OffsetAdjustment;
2648 OffsetAdjustment =
FileOffset.u.LowPart - AdjustOffset;
2680 *ReadSize = UsedSize - OffsetAdjustment;
2691# define MmspAssertSegmentsSorted(OBJ_) ((void)0)
2692# define MmspAssertSegmentsNoOverlap(OBJ_) ((void)0)
2693# define MmspAssertSegmentsPageAligned(OBJ_) ((void)0)
2702 for(
i = 1;
i < ImageSectionObject->NrSegments; ++
i )
2704 ASSERT(ImageSectionObject->Segments[
i].Image.VirtualAddress >=
2705 ImageSectionObject->Segments[
i - 1].Image.VirtualAddress);
2718 for(
i = 0;
i < ImageSectionObject->NrSegments; ++
i )
2720 ASSERT(ImageSectionObject->Segments[
i].Length.QuadPart > 0);
2724 ASSERT(ImageSectionObject->Segments[
i].Image.VirtualAddress >=
2725 (ImageSectionObject->Segments[
i - 1].Image.VirtualAddress +
2726 ImageSectionObject->Segments[
i - 1].Length.QuadPart));
2738 for(
i = 0;
i < ImageSectionObject->NrSegments; ++
i )
2740 ASSERT((ImageSectionObject->Segments[
i].Image.VirtualAddress %
PAGE_SIZE) == 0);
2741 ASSERT((ImageSectionObject->Segments[
i].Length.QuadPart %
PAGE_SIZE) == 0);
2755 if (Segment1->
Image.VirtualAddress > Segment2->
Image.VirtualAddress)
2757 else if (Segment1->
Image.VirtualAddress < Segment2->
Image.VirtualAddress)
2778 qsort(ImageSectionObject->Segments,
2779 ImageSectionObject->NrSegments,
2780 sizeof(ImageSectionObject->Segments[0]),
2808 ASSERT(ImageSectionObject->NrSegments >= 1);
2810 for (
i = 0;
i < ImageSectionObject->NrSegments; ++
i )
2812 if(ImageSectionObject->Segments[
i].Length.QuadPart == 0)
2826 if ((ImageSectionObject->Segments[
i - 1].Image.VirtualAddress +
2827 ImageSectionObject->Segments[
i - 1].Length.QuadPart) !=
2828 ImageSectionObject->Segments[
i].Image.VirtualAddress)
2862 EffectiveSegment = &ImageSectionObject->Segments[LastSegment];
2864 for (
i = 0;
i < ImageSectionObject->NrSegments; ++
i )
2881 EffectiveSegment->
Image.VirtualAddress;
2886 if (EffectiveSegment->
Image.FileOffset < VirtualOffset)
2896 EffectiveSegment->
Image.FileOffset -= VirtualOffset;
2911 if (EndOfEffectiveSegment ==
Segment->Image.VirtualAddress)
2915 ASSERT(LastSegment < ImageSectionObject->NrSegments);
2917 EffectiveSegment = &ImageSectionObject->Segments[LastSegment];
2919 if (LastSegment !=
i)
2939 else if (EndOfEffectiveSegment >
Segment->Image.VirtualAddress)
2941 static const ULONG FlagsToProtection[16] =
2961 unsigned ProtectionFlags;
2968 if (
Segment->Image.FileOffset != (EffectiveSegment->
Image.FileOffset +
2982 EffectiveSegment->
Image.VirtualAddress;
2990 ProtectionFlags = 0;
2993 ProtectionFlags |= 1 << 0;
2996 ProtectionFlags |= 1 << 1;
2999 ProtectionFlags |= 1 << 2;
3002 ProtectionFlags |= 1 << 3;
3004 ASSERT(ProtectionFlags < 16);
3005 EffectiveSegment->
Protection = FlagsToProtection[ProtectionFlags];
3023 ImageSectionObject->NrSegments = LastSegment + 1;
3034 PVOID FileHeaderBuffer;
3035 ULONG FileHeaderSize;
3037 ULONG OldNrSegments;
3057 if (FileHeaderSize == 0)
3080 if (ImageSectionObject->Segments)
3083 ImageSectionObject->Segments =
NULL;
3138 OldNrSegments = ImageSectionObject->
NrSegments;
3144 if (ImageSectionObject->
NrSegments < OldNrSegments)
3155 if (Segments ==
NULL)
3160 ImageSectionObject->
Segments = Segments;
3201 DPRINT1(
"Denying section creation due to missing cache initialization\n");
3236grab_image_section_object:
3240 ImageSectionObject =
FileObject->SectionObjectPointer->ImageSectionObject;
3248 ImageSectionObject =
FileObject->SectionObjectPointer->ImageSectionObject;
3251 if (ImageSectionObject ==
NULL)
3259 if (ImageSectionObject ==
NULL)
3270 if (
FileObject->SectionObjectPointer->ImageSectionObject !=
NULL)
3275 goto grab_image_section_object;
3278 FileObject->SectionObjectPointer->ImageSectionObject = ImageSectionObject;
3333 ImageSectionObject->
SegFlags &= ~MM_SEGMENT_INCREATE;
3345 ImageSectionObject->
SegFlags &= ~MM_IMAGE_SECTION_FLUSH_DELETE;
3424 DPRINT1(
"Mapping between 0x%p and 0x%p failed (%X).\n",
3508 if (SavedSwapEntry != 0)
3587 MmDereferenceSegment(
Segment);
3601 PVOID ImageBaseAddress = 0;
3603 DPRINT(
"Opening memory area Process %p BaseAddress %p\n",
3637 SectionSegments = ImageSectionObject->
Segments;
3644 for (
i = 0;
i < NrSegments;
i++)
3646 if (
Segment == &SectionSegments[
i])
3652 if (
i >= NrSegments)
3657 for (
i = 0;
i < NrSegments;
i++)
3660 ((
char*)ImageBaseAddress + (
ULONG_PTR)SectionSegments[
i].
Image.VirtualAddress);
3665 DPRINT1(
"MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3670 DPRINT(
"One mapping less for %p\n", ImageSectionObject->
FileObject->SectionObjectPointer);
3690 DPRINT1(
"MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3702 MmDereferenceSegment(
Segment);
3714 MmDereferenceSegment(
Segment);
3737 MmDereferenceSegment(
Segment);
3791 SectionInformationLength,
3838 switch(SectionInformationClass)
3881 DPRINT1(
"Unimplemented code path\n");
3942 DPRINT1(
"Unknown SectionInformationClass: %d\n", SectionInformationClass);
4021 DPRINT(
"Mapping ARM3 section into %s\n",
Process->ImageFileName);
4068 SectionSegments = ImageSectionObject->
Segments;
4080 for (
i = 0;
i < NrSegments;
i++)
4085 ImageSize =
max(ImageSize, MaxExtent);
4092 ((ImageBase + ImageSize) < ImageSize))
4127 for (
i = 0;
i < NrSegments;
i++)
4130 ((
char*)ImageBase + (
ULONG_PTR)SectionSegments[
i].
Image.VirtualAddress);
4134 &SectionSegments[
i],
4136 SectionSegments[
i].
Length.QuadPart,
4146 SBaseAddress = ((
char*)ImageBase + (
ULONG_PTR)SectionSegments[
i].
Image.VirtualAddress);
4159 DPRINT(
"Mapped %p for section pointer %p\n", ImageSectionObject, ImageSectionObject->
FileObject->SectionObjectPointer);
4270 DPRINT1(
"ERROR: File can't be truncated because it has an image section\n");
4282 if ((
Segment->SectionCount == 0) ||
4301 DPRINT1(
"ERROR: File can't be truncated because it has references held to its data section\n");
4306 MmDereferenceSegment(
Segment);
4308 DPRINT(
"FIXME: didn't check for outstanding write probes\n");