01431 :
01432
01433 This function creates
the necessary structures to allow
the mapping
01434 of an image
file.
01435
01436 The image
file is opened and verified
for correctness, a segment
01437 object
is created and initialized based on data in
the image
01438 header.
01439
01440 Arguments:
01441
01442
File - Supplies
the file object
for the image
file.
01443
01444 Segment - Returns
the segment object.
01445
01446 Return Value:
01447
01448 Returns
the status value.
01449
01450 TBS
01451
01452
01453 --*/
01454
01455 {
01456
NTSTATUS Status;
01457 ULONG_PTR EndingAddress;
01458 ULONG NumberOfPtes;
01459 ULONG SizeOfSegment;
01460 ULONG SectionVirtualSize;
01461 ULONG i;
01462 ULONG j;
01463
PCONTROL_AREA ControlArea;
01464
PSUBSECTION Subsection;
01465
PMMPTE PointerPte;
01466
MMPTE TempPte;
01467
MMPTE TempPteDemandZero;
01468 PVOID Base;
01469 PIMAGE_DOS_HEADER DosHeader;
01470 PIMAGE_NT_HEADERS NtHeader;
01471 PIMAGE_FILE_HEADER FileHeader;
01472 ULONG SizeOfImage;
01473 ULONG SizeOfHeaders;
01474
#if defined(_WIN64)
01475
PIMAGE_NT_HEADERS32 NtHeader32;
01476
#endif
01477
PIMAGE_SECTION_HEADER SectionTableEntry;
01478
PSEGMENT NewSegment;
01479 ULONG
SectorOffset;
01480 ULONG NumberOfSubsections;
01481 PFN_NUMBER PageFrameNumber;
01482 LARGE_INTEGER StartingOffset;
01483 PCHAR ExtendedHeader;
01484 PPFN_NUMBER Page;
01485 ULONG_PTR PreferredImageBase;
01486 ULONG_PTR NextVa;
01487
PKEVENT InPageEvent;
01488
PMDL Mdl;
01489 ULONG ImageFileSize;
01490 ULONG OffsetToSectionTable;
01491 ULONG ImageAlignment;
01492 ULONG RoundingAlignment;
01493 ULONG FileAlignment;
01494 BOOLEAN ImageCommit;
01495 BOOLEAN SectionCommit;
01496 IO_STATUS_BLOCK IoStatus;
01497 LARGE_INTEGER EndOfFile;
01498 ULONG NtHeaderSize;
01499 ULONG SubsectionsAllocated;
01500
PLARGE_CONTROL_AREA LargeControlArea;
01501
PSUBSECTION NewSubsection;
01502 ULONG OriginalProtection;
01503 ULONG LoaderFlags;
01504
01505
#if defined (_ALPHA_) || defined(_IA64_)
01506
01507
01508 BOOLEAN InvalidAlignmentAllowed =
FALSE;
01509
01510 ULONG TempNumberOfSubsections;
01511 PIMAGE_SECTION_HEADER TempSectionTableEntry;
01512 ULONG AdditionalSubsections;
01513 ULONG AdditionalPtes;
01514 ULONG AdditionalBasePtes;
01515 ULONG NewSubsectionsAllocated;
01516
PSEGMENT OldSegment;
01517
PMMPTE NewPointerPte;
01518
PMMPTE OldPointerPte;
01519 ULONG OrigNumberOfPtes;
01520
PCONTROL_AREA NewControlArea;
01521
01522
#endif
01523
01524 ExtendedHeader =
NULL;
01525
01526
01527
01528
01529
01530
PAGED_CODE();
01531
01532
01533
Status =
FsRtlGetFileSize (File, &EndOfFile);
01534
01535
if (
Status == STATUS_FILE_IS_A_DIRECTORY) {
01536
01537
01538
01539
01540
01541
return STATUS_INVALID_FILE_FOR_SECTION;
01542 }
01543
01544
if (!
NT_SUCCESS (Status)) {
01545
return Status;
01546 }
01547
01548
if (EndOfFile.HighPart != 0) {
01549
01550
01551
01552
01553
01554
return STATUS_INVALID_FILE_FOR_SECTION;
01555 }
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567 InPageEvent =
ExAllocatePoolWithTag (NonPagedPool,
01568
sizeof(
KEVENT) + MmSizeOfMdl (
01569 NULL,
01570 MM_MAXIMUM_IMAGE_HEADER),
01571 MMTEMPORARY);
01572
if (InPageEvent ==
NULL) {
01573
return STATUS_INSUFFICIENT_RESOURCES;
01574 }
01575
01576 Mdl = (
PMDL)(InPageEvent + 1);
01577
01578
01579
01580
01581
01582
KeInitializeEvent (InPageEvent, NotificationEvent, FALSE);
01583
01584
01585
01586
01587
01588
MmCreateMdl( Mdl, NULL, PAGE_SIZE);
01589 Mdl->
MdlFlags |=
MDL_PAGES_LOCKED;
01590
01591 PageFrameNumber =
MiGetPageForHeader();
01592
01593 Page = (PPFN_NUMBER)(Mdl + 1);
01594 *Page = PageFrameNumber;
01595
01596
ZERO_LARGE (StartingOffset);
01597
01598
CcZeroEndOfLastPage (File);
01599
01600
01601
01602
01603
01604
MiFlushDataSection (File);
01605
01606 Mdl->
MdlFlags |=
MDL_PAGES_LOCKED;
01607
Status =
IoPageRead (File,
01608 Mdl,
01609 &StartingOffset,
01610 InPageEvent,
01611 &IoStatus
01612 );
01613
01614
if (
Status == STATUS_PENDING) {
01615
KeWaitForSingleObject( InPageEvent,
01616 WrPageIn,
01617 KernelMode,
01618 FALSE,
01619 (PLARGE_INTEGER)NULL);
01620 }
01621
01622
if (Mdl->
MdlFlags &
MDL_MAPPED_TO_SYSTEM_VA) {
01623
MmUnmapLockedPages (Mdl->
MappedSystemVa, Mdl);
01624 }
01625
01626
if ((!
NT_SUCCESS(Status)) || (!
NT_SUCCESS(IoStatus.Status))) {
01627
if (
Status != STATUS_FILE_LOCK_CONFLICT) {
01628
Status = STATUS_INVALID_FILE_FOR_SECTION;
01629 }
01630
goto BadSection;
01631 }
01632
01633 Base =
MiMapImageHeaderInHyperSpace (PageFrameNumber);
01634 DosHeader = (PIMAGE_DOS_HEADER)Base;
01635
01636
if (IoStatus.Information !=
PAGE_SIZE) {
01637
01638
01639
01640
01641
01642
01643 RtlZeroMemory ((PVOID)((PCHAR)Base + IoStatus.Information),
01644 PAGE_SIZE - IoStatus.Information);
01645 }
01646
01647
01648
01649
01650
01651
01652
01653
01654
if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
01655
01656
Status = STATUS_INVALID_IMAGE_NOT_MZ;
01657
goto NeImage;
01658 }
01659
01660
#ifndef i386
01661
if (((ULONG)DosHeader->e_lfanew & 3) != 0) {
01662
01663
01664
01665
01666
01667
01668
Status = STATUS_INVALID_IMAGE_PROTECT;
01669
goto NeImage;
01670 }
01671
#endif
01672
01673
if ((ULONG)DosHeader->e_lfanew > EndOfFile.LowPart) {
01674
Status = STATUS_INVALID_IMAGE_PROTECT;
01675
goto NeImage;
01676 }
01677
01678
if (((ULONG)DosHeader->e_lfanew +
01679
sizeof(IMAGE_NT_HEADERS) +
01680 (16 *
sizeof(IMAGE_SECTION_HEADER))) <= (ULONG)DosHeader->e_lfanew) {
01681
Status = STATUS_INVALID_IMAGE_PROTECT;
01682
goto NeImage;
01683 }
01684
01685
if (((ULONG)DosHeader->e_lfanew +
01686
sizeof(IMAGE_NT_HEADERS) +
01687 (16 *
sizeof(IMAGE_SECTION_HEADER))) >
PAGE_SIZE) {
01688
01689
01690
01691
01692
01693
01694
01695 ExtendedHeader =
ExAllocatePoolWithTag (NonPagedPool,
01696 MM_MAXIMUM_IMAGE_HEADER,
01697 MMTEMPORARY);
01698
if (ExtendedHeader ==
NULL) {
01699
Status = STATUS_INSUFFICIENT_RESOURCES;
01700
goto NeImage;
01701 }
01702
01703
01704
01705
01706
01707
MmCreateMdl( Mdl, ExtendedHeader, MM_MAXIMUM_IMAGE_HEADER);
01708
01709
MmBuildMdlForNonPagedPool (Mdl);
01710
01711 StartingOffset.LowPart = PtrToUlong(PAGE_ALIGN ((ULONG)DosHeader->e_lfanew));
01712
01713
KeClearEvent (InPageEvent);
01714
Status =
IoPageRead (File,
01715 Mdl,
01716 &StartingOffset,
01717 InPageEvent,
01718 &IoStatus
01719 );
01720
01721
if (
Status == STATUS_PENDING) {
01722
KeWaitForSingleObject( InPageEvent,
01723 WrPageIn,
01724 KernelMode,
01725 FALSE,
01726 (PLARGE_INTEGER)NULL);
01727 }
01728
01729
if (Mdl->
MdlFlags &
MDL_MAPPED_TO_SYSTEM_VA) {
01730
MmUnmapLockedPages (Mdl->
MappedSystemVa, Mdl);
01731 }
01732
01733
if ((!
NT_SUCCESS(Status)) || (!
NT_SUCCESS(IoStatus.Status))) {
01734
if (
Status != STATUS_FILE_LOCK_CONFLICT) {
01735
Status = STATUS_INVALID_FILE_FOR_SECTION;
01736 }
01737
goto NeImage;
01738 }
01739 NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)ExtendedHeader +
01740
BYTE_OFFSET((ULONG)DosHeader->e_lfanew));
01741 NtHeaderSize =
MM_MAXIMUM_IMAGE_HEADER -
01742 (ULONG)(
BYTE_OFFSET((ULONG)DosHeader->e_lfanew));
01743
01744 }
else {
01745 NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)DosHeader +
01746 (ULONG)DosHeader->e_lfanew);
01747 NtHeaderSize =
PAGE_SIZE - (ULONG)DosHeader->e_lfanew;
01748 }
01749 FileHeader = &NtHeader->FileHeader;
01750
01751
01752
01753
01754
01755
Status =
MiVerifyImageHeader (NtHeader, DosHeader, NtHeaderSize);
01756
if (
Status != STATUS_SUCCESS) {
01757
goto NeImage;
01758 }
01759
01760
#if defined(_WIN64)
01761
if (NtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
01762
01763
01764
01765
01766
01767 NtHeader32 = (PIMAGE_NT_HEADERS32)NtHeader;
01768 NtHeader =
NULL;
01769 }
else {
01770 NtHeader32 =
NULL;
01771 }
01772
01773
if (NtHeader) {
01774
#endif
01775
ImageAlignment = NtHeader->OptionalHeader.SectionAlignment;
01776 FileAlignment = NtHeader->OptionalHeader.FileAlignment - 1;
01777 SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
01778 LoaderFlags = NtHeader->OptionalHeader.LoaderFlags;
01779
#if defined (_WIN64)
01780
}
else {
01781 ImageAlignment = NtHeader32->OptionalHeader.SectionAlignment;
01782 FileAlignment = NtHeader32->OptionalHeader.FileAlignment - 1;
01783 SizeOfImage = NtHeader32->OptionalHeader.SizeOfImage;
01784 LoaderFlags = NtHeader32->OptionalHeader.LoaderFlags;
01785 }
01786
#endif
01787
01788 RoundingAlignment = ImageAlignment;
01789 NumberOfSubsections = FileHeader->NumberOfSections;
01790
01791
if (ImageAlignment <
PAGE_SIZE) {
01792
01793
01794
01795
01796
01797
01798 ControlArea =
ExAllocatePoolWithTag (NonPagedPool,
01799 (ULONG)(
sizeof(
CONTROL_AREA) + (
sizeof(
SUBSECTION))),
01800 MMCONTROL);
01801 SubsectionsAllocated = 1;
01802 }
else {
01803
01804
01805
01806
01807
01808
01809 ControlArea =
ExAllocatePoolWithTag(NonPagedPool,
01810 (ULONG)(
sizeof(CONTROL_AREA) +
01811 (
sizeof(
SUBSECTION) *
01812 (NumberOfSubsections + 1))),
01813 'iCmM');
01814 SubsectionsAllocated = NumberOfSubsections + 1;
01815 }
01816
01817
if (ControlArea ==
NULL) {
01818
01819
01820
01821
01822
01823
Status = STATUS_INSUFFICIENT_RESOURCES;
01824
goto NeImage;
01825 }
01826
01827
01828
01829
01830
01831 RtlZeroMemory (ControlArea,
01832
sizeof(CONTROL_AREA) +
sizeof(
SUBSECTION));
01833
01834 ControlArea->
NonPagedPoolUsage =
EX_REAL_POOL_USAGE(
sizeof(CONTROL_AREA) +
01835
sizeof(
SUBSECTION) *
01836 SubsectionsAllocated);
01837
01838
ASSERT (ControlArea->
u.Flags.GlobalOnlyPerSession == 0);
01839
01840 Subsection = (
PSUBSECTION)(ControlArea + 1);
01841
01842 NumberOfPtes =
BYTES_TO_PAGES (SizeOfImage);
01843
01844
if (NumberOfPtes == 0) {
01845
ExFreePool (ControlArea);
01846
Status = STATUS_INVALID_IMAGE_FORMAT;
01847
goto NeImage;
01848 }
01849
01850
#if defined (_ALPHA_) || defined(_IA64_)
01851
if (ImageAlignment <
PAGE_SIZE && KeGetPreviousMode() !=
KernelMode &&
01852 (FileHeader->Machine < USER_SHARED_DATA->ImageNumberLow ||
01853 FileHeader->Machine > USER_SHARED_DATA->ImageNumberHigh)) {
01854
01855 InvalidAlignmentAllowed =
TRUE;
01856 }
01857 OrigNumberOfPtes = NumberOfPtes;
01858
#endif
01859
01860 SizeOfSegment =
sizeof(
SEGMENT) + (
sizeof(
MMPTE) * (NumberOfPtes - 1)) +
01861
sizeof(SECTION_IMAGE_INFORMATION);
01862
01863 NewSegment =
ExAllocatePoolWithTag (PagedPool,
01864 SizeOfSegment,
01865 MMSECT);
01866
01867
if (NewSegment ==
NULL) {
01868
01869
01870
01871
01872
01873
ExFreePool (ControlArea);
01874
Status = STATUS_INSUFFICIENT_RESOURCES;
01875
goto NeImage;
01876 }
01877 *Segment = NewSegment;
01878 RtlZeroMemory (NewSegment,
sizeof(
SEGMENT));
01879
01880
01881
01882
01883
01884 PointerPte = &NewSegment->ThePtes[0];
01885 i = (ULONG) (((ULONG_PTR)PointerPte >>
PTE_SHIFT) &
01886 ((
MM_PROTO_PTE_ALIGNMENT /
PAGE_SIZE) - 1));
01887
01888
if (i != 0) {
01889 i = (
MM_PROTO_PTE_ALIGNMENT /
PAGE_SIZE) - i;
01890 }
01891
01892 NewSegment->PrototypePte = &NewSegment->ThePtes[i];
01893
01894 NewSegment->ControlArea = ControlArea;
01895 NewSegment->ImageInformation =
01896 (PSECTION_IMAGE_INFORMATION)((PCHAR)NewSegment +
sizeof(
SEGMENT) +
01897 (
sizeof(
MMPTE) * (NumberOfPtes - 1)));
01898 NewSegment->TotalNumberOfPtes = NumberOfPtes;
01899 NewSegment->NonExtendedPtes = NumberOfPtes;
01900 NewSegment->SizeOfSegment = (ULONG_PTR)NumberOfPtes *
PAGE_SIZE;
01901
01902 RtlZeroMemory (NewSegment->ImageInformation,
01903 sizeof (SECTION_IMAGE_INFORMATION));
01904
01905
01906
01907
01908
01909
01910
#define INIT_IMAGE_INFORMATION(OptHdr) { \
01911
NewSegment->ImageInformation->TransferAddress = \
01912
(PVOID)((ULONG_PTR)((OptHdr).ImageBase) + \
01913
(OptHdr).AddressOfEntryPoint); \
01914
NewSegment->ImageInformation->MaximumStackSize = \
01915
(OptHdr).SizeOfStackReserve; \
01916
NewSegment->ImageInformation->CommittedStackSize = \
01917
(OptHdr).SizeOfStackCommit; \
01918
NewSegment->ImageInformation->SubSystemType = \
01919
(OptHdr).Subsystem; \
01920
NewSegment->ImageInformation->SubSystemMajorVersion = (USHORT)((OptHdr).MajorSubsystemVersion); \
01921
NewSegment->ImageInformation->SubSystemMinorVersion = (USHORT)((OptHdr).MinorSubsystemVersion); \
01922
NewSegment->ImageInformation->DllCharacteristics = \
01923
(OptHdr).DllCharacteristics; \
01924
NewSegment->ImageInformation->ImageContainsCode = \
01925
(BOOLEAN)(((OptHdr).SizeOfCode != 0) || \
01926
((OptHdr).AddressOfEntryPoint != 0)); \
01927
}
01928
01929
#if defined (_WIN64)
01930
if (NtHeader) {
01931
#endif
01932
INIT_IMAGE_INFORMATION(NtHeader->OptionalHeader);
01933
#if defined (_WIN64)
01934
}
else {
01935
01936
INIT_IMAGE_INFORMATION(NtHeader32->OptionalHeader);
01937 }
01938
#endif
01939
#undef INIT_IMAGE_INFORMATION
01940
01941 NewSegment->ImageInformation->ImageCharacteristics =
01942 FileHeader->Characteristics;
01943 NewSegment->ImageInformation->Machine =
01944 FileHeader->Machine;
01945
01946 ControlArea->
Segment = NewSegment;
01947 ControlArea->
NumberOfSectionReferences = 1;
01948 ControlArea->
NumberOfUserReferences = 1;
01949 ControlArea->
u.Flags.BeingCreated = 1;
01950 ControlArea->
PagedPoolUsage =
EX_REAL_POOL_USAGE((
sizeof(
SEGMENT) + (NumberOfPtes *
sizeof(
MMPTE))));
01951
01952
if (ImageAlignment <
PAGE_SIZE) {
01953
01954
01955
01956
01957
01958
01959 ControlArea->
NumberOfSubsections = 1;
01960 }
else {
01961 ControlArea->
NumberOfSubsections = (
USHORT)NumberOfSubsections;
01962 }
01963
01964 ControlArea->
u.Flags.Image = 1;
01965 ControlArea->
u.Flags.File = 1;
01966
01967
if ((FILE_FLOPPY_DISKETTE &
File->DeviceObject->Characteristics) ||
01968 ((FileHeader->Characteristics &
01969 IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP) &&
01970 (FILE_REMOVABLE_MEDIA &
File->DeviceObject->Characteristics)) ||
01971 ((FileHeader->Characteristics &
01972 IMAGE_FILE_NET_RUN_FROM_SWAP) &&
01973 (FILE_REMOTE_DEVICE &
File->DeviceObject->Characteristics))) {
01974
01975
01976
01977
01978
01979
01980
01981 ControlArea->
u.Flags.FloppyMedia = 1;
01982 }
01983
01984
if (FILE_REMOTE_DEVICE &
File->DeviceObject->Characteristics) {
01985
01986
01987
01988
01989
01990 ControlArea->
u.Flags.Networked = 1;
01991 }
01992
01993 ControlArea->
FilePointer =
File;
01994
01995
01996
01997
01998
01999 Subsection->
ControlArea = ControlArea;
02000
#if defined(_WIN64)
02001
if (NtHeader) {
02002
#endif
02003
NextVa = NtHeader->OptionalHeader.ImageBase;
02004
#if defined(_WIN64)
02005
}
else {
02006 NextVa = NtHeader32->OptionalHeader.ImageBase;
02007 }
02008
#endif
02009
02010
02011
if ((NextVa & (
X64K - 1)) != 0) {
02012
02013
02014
02015
02016
02017
goto BadPeImageSegment;
02018 }
02019
02020 NewSegment->BasedAddress = (PVOID)NextVa;
02021
#if defined(_WIN64)
02022
if (NtHeader) {
02023
#endif
02024
SizeOfHeaders = NtHeader->OptionalHeader.SizeOfHeaders;
02025
#if defined(_WIN64)
02026
}
else {
02027 SizeOfHeaders = NtHeader32->OptionalHeader.SizeOfHeaders;
02028 }
02029
#endif
02030
02031
if (SizeOfHeaders >= SizeOfImage) {
02032
goto BadPeImageSegment;
02033 }
02034
02035 Subsection->
PtesInSubsection =
MI_ROUND_TO_SIZE (
02036 SizeOfHeaders,
02037 ImageAlignment
02038 ) >>
PAGE_SHIFT;
02039
02040 PointerPte = NewSegment->PrototypePte;
02041 Subsection->
SubsectionBase = PointerPte;
02042
02043 TempPte.
u.Long =
MiGetSubsectionAddressForPte (Subsection);
02044 TempPte.
u.Soft.Prototype = 1;
02045
02046 NewSegment->SegmentPteTemplate = TempPte;
02047
SectorOffset = 0;
02048
02049
if (ImageAlignment <
PAGE_SIZE) {
02050
02051
02052
02053
02054
02055
02056 PointerPte = NewSegment->PrototypePte;
02057
02058 Subsection->
PtesInSubsection = NumberOfPtes;
02059
02060 Subsection->
NumberOfFullSectors =
02061 (ULONG)(EndOfFile.QuadPart >>
MMSECTOR_SHIFT);
02062
02063
ASSERT ((ULONG)(EndOfFile.HighPart & 0xFFFFF000) == 0);
02064
02065 Subsection->
u.SubsectionFlags.SectorEndOffset =
02066 EndOfFile.LowPart &
MMSECTOR_MASK;
02067
02068 Subsection->
u.SubsectionFlags.Protection =
MM_EXECUTE_WRITECOPY;
02069
02070
02071
02072
02073
02074
02075
02076
02077 TempPte.
u.Soft.Protection =
MM_EXECUTE_WRITECOPY;
02078
02079 NewSegment->SegmentPteTemplate = TempPte;
02080
02081
02082
#if defined (_ALPHA_) || defined(_IA64_)
02083
02084
02085
02086
02087
02088
02089
02090
if (InvalidAlignmentAllowed) {
02091
02092 TempPteDemandZero.
u.Long = 0;
02093 TempPteDemandZero.
u.Soft.Protection =
MM_EXECUTE_WRITECOPY;
02094
SectorOffset = 0;
02095
02096
for (i = 0; i < NumberOfPtes; i += 1) {
02097
02098
02099
02100
02101
02102
if (
SectorOffset < EndOfFile.LowPart) {
02103
02104
02105
02106
02107
02108
MI_WRITE_INVALID_PTE (PointerPte, TempPte);
02109
02110 }
else {
02111
02112
02113
02114
02115
02116
MI_WRITE_INVALID_PTE (PointerPte, TempPteDemandZero);
02117 }
02118
02119
SectorOffset +=
PAGE_SIZE;
02120 PointerPte += 1;
02121 }
02122
02123 }
else
02124
#endif
02125
{
02126
02127
for (i = 0; i < NumberOfPtes; i += 1) {
02128
02129
02130
02131
02132
02133
MI_WRITE_INVALID_PTE (PointerPte, TempPte);
02134 PointerPte += 1;
02135 }
02136 }
02137
02138 NewSegment->ImageCommitment = NumberOfPtes;
02139
02140
02141
02142
02143
02144
02145 TempPte.
u.Long = 0;
02146
02147 }
else {
02148
02149
02150
02151
02152
02153
if (Subsection->
PtesInSubsection > NumberOfPtes) {
02154
02155
02156
02157
02158
02159
goto BadPeImageSegment;
02160 }
02161 NumberOfPtes -= Subsection->
PtesInSubsection;
02162
02163 Subsection->
NumberOfFullSectors =
02164 SizeOfHeaders >>
MMSECTOR_SHIFT;
02165
02166 Subsection->
u.SubsectionFlags.SectorEndOffset =
02167 SizeOfHeaders &
MMSECTOR_MASK;
02168
02169 Subsection->
u.SubsectionFlags.ReadOnly = 1;
02170 Subsection->
u.SubsectionFlags.CopyOnWrite = 1;
02171 Subsection->
u.SubsectionFlags.Protection =
MM_READONLY;
02172
02173 TempPte.
u.Soft.Protection =
MM_READONLY;
02174 NewSegment->SegmentPteTemplate = TempPte;
02175
02176
for (i = 0; i < Subsection->
PtesInSubsection; i += 1) {
02177
02178
02179
02180
02181
02182
if (
SectorOffset < SizeOfHeaders) {
02183
MI_WRITE_INVALID_PTE (PointerPte, TempPte);
02184 }
else {
02185
MI_WRITE_INVALID_PTE (PointerPte, ZeroPte);
02186 }
02187
SectorOffset +=
PAGE_SIZE;
02188 PointerPte += 1;
02189 NextVa +=
PAGE_SIZE;
02190 }
02191 }
02192
02193
02194
02195
02196
02197
#if defined(_WIN64)
02198
if (NtHeader) {
02199
#endif
02200
PreferredImageBase = NtHeader->OptionalHeader.ImageBase;
02201
#if defined(_WIN64)
02202
}
else {
02203 PreferredImageBase = NtHeader32->OptionalHeader.ImageBase;
02204 }
02205
#endif
02206
02207
02208
02209
02210
02211
02212 SectionTableEntry =
NULL;
02213 OffsetToSectionTable =
sizeof(ULONG) +
02214
sizeof(IMAGE_FILE_HEADER) +
02215 FileHeader->SizeOfOptionalHeader;
02216
02217
if ((
BYTE_OFFSET(NtHeader) + OffsetToSectionTable +
02218
#if defined (_WIN64)
02219
BYTE_OFFSET(NtHeader32) +
02220
#endif
02221
((NumberOfSubsections + 1) *
02222
sizeof (IMAGE_SECTION_HEADER))) <=
PAGE_SIZE) {
02223
02224
02225
02226
02227
02228
#if defined(_WIN64)
02229
if (NtHeader32) {
02230 SectionTableEntry = (PIMAGE_SECTION_HEADER)((PCHAR)NtHeader32 +
02231 OffsetToSectionTable);
02232 }
else
02233
#endif
02234
{
02235 SectionTableEntry = (PIMAGE_SECTION_HEADER)((PCHAR)NtHeader +
02236 OffsetToSectionTable);
02237 }
02238
02239 }
else {
02240
02241
02242
02243
02244
02245
02246
if (ExtendedHeader !=
NULL) {
02247
02248
#if defined(_WIN64)
02249
if (NtHeader32) {
02250 SectionTableEntry = (PIMAGE_SECTION_HEADER)((PCHAR)NtHeader32 +
02251 OffsetToSectionTable);
02252 }
else
02253
#endif
02254
{
02255 SectionTableEntry = (PIMAGE_SECTION_HEADER)((PCHAR)NtHeader +
02256 OffsetToSectionTable);
02257 }
02258
02259
02260
02261
02262
02263
02264
if ((((PCHAR)SectionTableEntry +
02265 ((NumberOfSubsections + 1) *
02266
sizeof (IMAGE_SECTION_HEADER))) -
02267 (PCHAR)ExtendedHeader) >
02268
MM_MAXIMUM_IMAGE_HEADER) {
02269 SectionTableEntry =
NULL;
02270
02271 }
02272 }
02273 }
02274
02275
if (SectionTableEntry ==
NULL) {
02276
02277
02278
02279
02280
02281
02282
02283
if (ExtendedHeader ==
NULL) {
02284 ExtendedHeader =
ExAllocatePoolWithTag (NonPagedPool,
02285 MM_MAXIMUM_IMAGE_HEADER,
02286 MMTEMPORARY);
02287
if (ExtendedHeader ==
NULL) {
02288
ExFreePool (NewSegment);
02289
ExFreePool (ControlArea);
02290
Status = STATUS_INSUFFICIENT_RESOURCES;
02291
goto NeImage;
02292 }
02293
02294
02295
02296
02297
02298
MmCreateMdl( Mdl, ExtendedHeader, MM_MAXIMUM_IMAGE_HEADER);
02299
02300
MmBuildMdlForNonPagedPool (Mdl);
02301 }
02302
02303 StartingOffset.LowPart = PtrToUlong(PAGE_ALIGN (
02304 (ULONG)DosHeader->e_lfanew +
02305 OffsetToSectionTable));
02306
02307 SectionTableEntry = (PIMAGE_SECTION_HEADER)((PCHAR)ExtendedHeader +
02308
BYTE_OFFSET((ULONG)DosHeader->e_lfanew +
02309 OffsetToSectionTable));
02310
02311
KeClearEvent (InPageEvent);
02312
Status =
IoPageRead (File,
02313 Mdl,
02314 &StartingOffset,
02315 InPageEvent,
02316 &IoStatus
02317 );
02318
02319
if (
Status == STATUS_PENDING) {
02320
KeWaitForSingleObject( InPageEvent,
02321 WrPageIn,
02322 KernelMode,
02323 FALSE,
02324 (PLARGE_INTEGER)NULL);
02325 }
02326
02327
if (Mdl->
MdlFlags &
MDL_MAPPED_TO_SYSTEM_VA) {
02328
MmUnmapLockedPages (Mdl->
MappedSystemVa, Mdl);
02329 }
02330
02331
if ((!
NT_SUCCESS(Status)) || (!
NT_SUCCESS(IoStatus.Status))) {
02332
if (
Status != STATUS_FILE_LOCK_CONFLICT) {
02333
Status = STATUS_INVALID_FILE_FOR_SECTION;
02334 }
02335
ExFreePool (NewSegment);
02336
ExFreePool (ControlArea);
02337
goto NeImage;
02338 }
02339
02340
02341
02342
02343
02344
02345
02346 }
02347
02348
if (TempPte.
u.Long == 0
02349
#if defined (_ALPHA_) || defined(_IA64_)
02350
&& (!InvalidAlignmentAllowed)
02351
#endif
02352
) {
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
Status = STATUS_SUCCESS;
02364
02365
while (NumberOfSubsections > 0) {
02366
if (SectionTableEntry->Misc.VirtualSize == 0) {
02367 SectionVirtualSize = SectionTableEntry->SizeOfRawData;
02368 }
else {
02369 SectionVirtualSize = SectionTableEntry->Misc.VirtualSize;
02370 }
02371
02372
02373
02374
02375
02376
if (SectionTableEntry->PointerToRawData +
02377 SectionTableEntry->SizeOfRawData <
02378 SectionTableEntry->PointerToRawData) {
02379
02380 KdPrint((
"MMCREASECT: invalid section/file size %Z\n",
02381 &
File->FileName));
02382
02383
Status = STATUS_INVALID_IMAGE_FORMAT;
02384
break;
02385 }
02386
02387
02388
02389
02390
02391
02392
if (((SectionTableEntry->PointerToRawData !=
02393 SectionTableEntry->VirtualAddress))
02394 ||
02395 (SectionVirtualSize > SectionTableEntry->SizeOfRawData)) {
02396
02397 KdPrint((
"MMCREASECT: invalid BSS/Trailingzero %Z\n",
02398 &
File->FileName));
02399
02400
Status = STATUS_INVALID_IMAGE_FORMAT;
02401
break;
02402 }
02403
02404
02405 SectionTableEntry += 1;
02406 NumberOfSubsections -= 1;
02407 }
02408
02409
02410
if (!
NT_SUCCESS(Status)) {
02411
ExFreePool (NewSegment);
02412
ExFreePool (ControlArea);
02413
goto NeImage;
02414 }
02415
02416
goto PeReturnSuccess;
02417
02418 }
02419
#if defined (_ALPHA_) || defined(_IA64_)
02420
02421
else if (TempPte.
u.Long == 0 && InvalidAlignmentAllowed) {
02422
02423 TempNumberOfSubsections = NumberOfSubsections;
02424 TempSectionTableEntry = SectionTableEntry;
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440 AdditionalSubsections = 0;
02441 AdditionalPtes = 0;
02442 AdditionalBasePtes = 0;
02443 RoundingAlignment =
PAGE_SIZE;
02444
02445
while (TempNumberOfSubsections > 0) {
02446 ULONG EndOfSection;
02447 ULONG ExtraPages;
02448
02449
if (TempSectionTableEntry->Misc.VirtualSize == 0) {
02450 SectionVirtualSize = TempSectionTableEntry->SizeOfRawData;
02451 }
else {
02452 SectionVirtualSize = TempSectionTableEntry->Misc.VirtualSize;
02453 }
02454
02455 EndOfSection = TempSectionTableEntry->PointerToRawData +
02456 TempSectionTableEntry->SizeOfRawData;
02457
02458
02459
02460
02461
02462
if (EndOfSection < TempSectionTableEntry->PointerToRawData) {
02463
02464 KdPrint((
"MMCREASECT: invalid section/file size %Z\n",
02465 &
File->FileName));
02466
02467
Status = STATUS_INVALID_IMAGE_FORMAT;
02468
02469
ExFreePool (NewSegment);
02470
ExFreePool (ControlArea);
02471
goto NeImage;
02472 }
02473
02474
02475
02476
02477
02478
02479
02480
02481
if ((EndOfSection <= EndOfFile.LowPart) &&
02482 (EndOfSection > SizeOfImage)) {
02483
02484
02485
02486
02487
02488
02489 ExtraPages =
MI_ROUND_TO_SIZE (EndOfSection - SizeOfImage, RoundingAlignment) >>
PAGE_SHIFT;
02490
if (ExtraPages > AdditionalBasePtes) {
02491 AdditionalBasePtes = ExtraPages;
02492 }
02493 }
02494
02495
02496
02497
if ((TempSectionTableEntry->Characteristics & IMAGE_SCN_MEM_SHARED) &&
02498 (!(TempSectionTableEntry->Characteristics & IMAGE_SCN_MEM_EXECUTE) ||
02499 (TempSectionTableEntry->Characteristics & IMAGE_SCN_MEM_WRITE))) {
02500 AdditionalPtes +=
02501
MI_ROUND_TO_SIZE (SectionVirtualSize, RoundingAlignment) >>
02502
PAGE_SHIFT;
02503 AdditionalSubsections += 1;
02504 }
02505
02506 TempSectionTableEntry += 1;
02507 TempNumberOfSubsections -= 1;
02508 }
02509
02510
if (AdditionalBasePtes == 0 && (AdditionalSubsections == 0 || AdditionalPtes == 0)) {
02511
02512
goto PeReturnSuccess;
02513 }
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524 NewSubsectionsAllocated = SubsectionsAllocated +
02525 AdditionalSubsections;
02526
02527 NewControlArea =
ExAllocatePoolWithTag(NonPagedPool,
02528 (ULONG) (
sizeof(CONTROL_AREA) +
02529 (
sizeof(
SUBSECTION) *
02530 NewSubsectionsAllocated)),
02531 'iCmM');
02532
if (NewControlArea ==
NULL) {
02533
ExFreePool (NewSegment);
02534
ExFreePool (ControlArea);
02535
Status = STATUS_INSUFFICIENT_RESOURCES;
02536
goto NeImage;
02537 }
02538
02539
02540
02541
02542
02543 RtlMoveMemory (NewControlArea, ControlArea,
02544
sizeof(CONTROL_AREA) +
02545
sizeof(
SUBSECTION) * SubsectionsAllocated);
02546
02547 NewControlArea->
NonPagedPoolUsage =
02548
EX_REAL_POOL_USAGE(
sizeof(CONTROL_AREA) +
02549 (
sizeof(
SUBSECTION) *
02550 NewSubsectionsAllocated));
02551
02552 NewControlArea->
NumberOfSubsections = (
USHORT) NewSubsectionsAllocated;
02553
02554
02555
02556
02557
02558
02559
02560 OldSegment = NewSegment;
02561
02562
02563 OrigNumberOfPtes += AdditionalBasePtes;
02564
02565 SizeOfSegment =
sizeof(
SEGMENT) +
02566 (
sizeof(
MMPTE) * (OrigNumberOfPtes + AdditionalPtes - 1)) +
02567
sizeof(SECTION_IMAGE_INFORMATION);
02568
02569 NewSegment =
ExAllocatePoolWithTag (PagedPool,
02570 SizeOfSegment,
02571 MMSECT);
02572
02573
if (NewSegment ==
NULL) {
02574
02575
02576
02577
02578
02579
ExFreePool (ControlArea);
02580
ExFreePool (NewControlArea);
02581
ExFreePool (OldSegment);
02582
Status = STATUS_INSUFFICIENT_RESOURCES;
02583
goto NeImage;
02584 }
02585
02586 *Segment = NewSegment;
02587 RtlMoveMemory (NewSegment, OldSegment,
sizeof(SEGMENT));
02588
02589
02590
02591
02592
02593 NewPointerPte = &NewSegment->ThePtes[0];
02594 i = (ULONG) (((ULONG_PTR)NewPointerPte >>
PTE_SHIFT) &
02595 ((
MM_PROTO_PTE_ALIGNMENT /
PAGE_SIZE) - 1));
02596
02597
if (i != 0) {
02598 i = (
MM_PROTO_PTE_ALIGNMENT /
PAGE_SIZE) - i;
02599 }
02600
02601 NewSegment->PrototypePte = &NewSegment->ThePtes[i];
02602
if (i != 0) {
02603 RtlZeroMemory (&NewSegment->ThePtes[0],
sizeof(
MMPTE) * i);
02604 }
02605 PointerPte = NewSegment->PrototypePte +
02606 (PointerPte - OldSegment->
PrototypePte);
02607
02608 NewSegment->ControlArea = NewControlArea;
02609 NewSegment->ImageInformation =
02610 (PSECTION_IMAGE_INFORMATION)((PCHAR)NewSegment +
sizeof(
SEGMENT) +
02611 (
sizeof(
MMPTE) * (OrigNumberOfPtes + AdditionalPtes - 1)));
02612 NewSegment->TotalNumberOfPtes = OrigNumberOfPtes + AdditionalPtes;
02613 NewSegment->NonExtendedPtes = OrigNumberOfPtes + AdditionalPtes;
02614 NewSegment->SizeOfSegment = (ULONG_PTR)(OrigNumberOfPtes + AdditionalPtes) *
PAGE_SIZE;
02615
02616 RtlMoveMemory (NewSegment->ImageInformation,
02617 OldSegment->
ImageInformation,
02618 sizeof (SECTION_IMAGE_INFORMATION));
02619
02620
02621
02622
02623
02624
02625
02626 NewControlArea->
Segment = NewSegment;
02627 NewControlArea->
PagedPoolUsage =
EX_REAL_POOL_USAGE((
sizeof(SEGMENT) +
02628 ((OrigNumberOfPtes + AdditionalPtes) *
sizeof(
MMPTE))));
02629
02630 Subsection = (
PSUBSECTION)(ControlArea + 1);
02631 NewSubsection = (
PSUBSECTION)(NewControlArea + 1);
02632 NewSubsection->
PtesInSubsection += AdditionalBasePtes;
02633
02634
for (i = 0; i < SubsectionsAllocated; i += 1) {
02635
02636
02637
02638
02639
02640
02641 NewSubsection->
ControlArea = (
PCONTROL_AREA) NewControlArea;
02642
02643 NewSubsection->
SubsectionBase = NewSegment->PrototypePte +
02644 (Subsection->
SubsectionBase - OldSegment->
PrototypePte);
02645
02646 NewPointerPte = NewSegment->PrototypePte;
02647 OldPointerPte = OldSegment->
PrototypePte;
02648
02649 TempPte.
u.Long =
MiGetSubsectionAddressForPte (NewSubsection);
02650 TempPte.
u.Soft.Prototype = 1;
02651
02652
for (j = 0; j < OldSegment->
TotalNumberOfPtes+AdditionalBasePtes; j += 1) {
02653
02654
if ((OldPointerPte->
u.Soft.Prototype == 1) &&
02655 (
MiGetSubsectionAddress (OldPointerPte) == Subsection)) {
02656 OriginalProtection =
MI_GET_PROTECTION_FROM_SOFT_PTE (OldPointerPte);
02657 TempPte.
u.Soft.Protection = OriginalProtection;
02658
MI_WRITE_INVALID_PTE (NewPointerPte, TempPte);
02659 }
02660
else if (i == 0) {
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673 OriginalProtection =
MI_GET_PROTECTION_FROM_SOFT_PTE (OldPointerPte);
02674 TempPteDemandZero.
u.Long = 0;
02675 TempPteDemandZero.
u.Soft.Protection = OriginalProtection;
02676
MI_WRITE_INVALID_PTE (NewPointerPte, TempPteDemandZero);
02677 }
02678
02679 NewPointerPte += 1;
02680
02681
02682
if (j < OldSegment->
TotalNumberOfPtes-1) {
02683 OldPointerPte += 1;
02684 }
02685 }
02686
02687 Subsection += 1;
02688 NewSubsection += 1;
02689 }
02690
02691
02692 RtlZeroMemory (NewSubsection,
02693
sizeof(
SUBSECTION) * AdditionalSubsections);
02694
02695
ExFreePool (OldSegment);
02696
ExFreePool (ControlArea);
02697 ControlArea = (
PCONTROL_AREA) NewControlArea;
02698
02699
02700
02701
02702
02703
02704 SubsectionsAllocated = NewSubsectionsAllocated;
02705 Subsection = NewSubsection - 1;
02706 NumberOfPtes = AdditionalPtes;
02707
02708
02709
02710
02711
if (AdditionalSubsections == 0 || AdditionalPtes == 0) {
02712
02713
goto PeReturnSuccess;
02714 }
02715 }
02716
#endif
02717
02718
while (NumberOfSubsections > 0) {
02719
02720
#if defined (_ALPHA_) || defined(_IA64_)
02721
if (!InvalidAlignmentAllowed ||
02722 ((SectionTableEntry->Characteristics & IMAGE_SCN_MEM_SHARED) &&
02723 (!(SectionTableEntry->Characteristics & IMAGE_SCN_MEM_EXECUTE) ||
02724 (SectionTableEntry->Characteristics & IMAGE_SCN_MEM_WRITE)))) {
02725
#endif
02726
02727
02728
02729
02730
02731
if (SectionTableEntry->Misc.VirtualSize == 0) {
02732 SectionVirtualSize = SectionTableEntry->SizeOfRawData;
02733 }
else {
02734 SectionVirtualSize = SectionTableEntry->Misc.VirtualSize;
02735 }
02736
02737
02738
02739
02740
02741
02742
02743
if (SectionTableEntry->SizeOfRawData == 0) {
02744 SectionTableEntry->PointerToRawData = 0;
02745 }
02746
02747
02748
02749
02750
02751
if (SectionTableEntry->PointerToRawData +
02752 SectionTableEntry->SizeOfRawData <
02753 SectionTableEntry->PointerToRawData) {
02754
02755
goto BadPeImageSegment;
02756 }
02757
02758
02759 Subsection += 1;
02760 Subsection->
ControlArea = ControlArea;
02761 Subsection->
NextSubsection = (
PSUBSECTION)
NULL;
02762 Subsection->
UnusedPtes = 0;
02763
02764
if (((NextVa !=
02765 (PreferredImageBase + SectionTableEntry->VirtualAddress))
02766
02767
#if defined (_ALPHA_) || defined(_IA64_)
02768
&& !InvalidAlignmentAllowed
02769
#endif
02770
02771 ) ||
02772 (SectionVirtualSize == 0)) {
02773
02774
02775
02776
02777
02778
02779
goto BadPeImageSegment;
02780 }
02781
02782 Subsection->
PtesInSubsection =
02783
MI_ROUND_TO_SIZE (SectionVirtualSize, RoundingAlignment)
02784 >>
PAGE_SHIFT;
02785
02786
if (Subsection->
PtesInSubsection > NumberOfPtes) {
02787
02788
02789
02790
02791
02792
goto BadPeImageSegment;
02793 }
02794 NumberOfPtes -= Subsection->
PtesInSubsection;
02795
02796 Subsection->
u.LongFlags = 0;
02797 Subsection->
StartingSector =
02798 SectionTableEntry->PointerToRawData >>
MMSECTOR_SHIFT;
02799
02800
02801
02802
02803
02804 EndingAddress = (SectionTableEntry->PointerToRawData +
02805 SectionTableEntry->SizeOfRawData +
02806 FileAlignment) & ~FileAlignment;
02807
02808 Subsection->
NumberOfFullSectors = (ULONG)
02809 ((EndingAddress >>
MMSECTOR_SHIFT) -
02810 Subsection->
StartingSector);
02811
02812 Subsection->
u.SubsectionFlags.SectorEndOffset =
02813 (ULONG) EndingAddress &
MMSECTOR_MASK;
02814
02815 Subsection->
SubsectionBase = PointerPte;
02816
02817
02818
02819
02820
02821 TempPte.
u.Long = 0;
02822 TempPteDemandZero.
u.Long = 0;
02823
02824 TempPte.
u.Long =
MiGetSubsectionAddressForPte (Subsection);
02825 TempPte.
u.Soft.Prototype = 1;
02826 ImageFileSize = SectionTableEntry->PointerToRawData +
02827 SectionTableEntry->SizeOfRawData;
02828 TempPte.
u.Soft.Protection =
02829
MiGetImageProtection (SectionTableEntry->Characteristics);
02830 TempPteDemandZero.
u.Soft.Protection = TempPte.
u.Soft.Protection;
02831
02832
if (SectionTableEntry->PointerToRawData == 0) {
02833 TempPte = TempPteDemandZero;
02834 }
02835
02836 Subsection->
u.SubsectionFlags.ReadOnly = 1;
02837 Subsection->
u.SubsectionFlags.CopyOnWrite = 1;
02838 Subsection->
u.SubsectionFlags.Protection =
MI_GET_PROTECTION_FROM_SOFT_PTE (&TempPte);
02839
02840
if (TempPte.
u.Soft.Protection &
MM_PROTECTION_WRITE_MASK) {
02841
if ((TempPte.
u.Soft.Protection &
MM_COPY_ON_WRITE_MASK)
02842 ==
MM_COPY_ON_WRITE_MASK) {
02843
02844
02845
02846
02847
02848
02849 ImageCommit =
TRUE;
02850 }
else {
02851
02852
02853
02854
02855
02856
02857 SectionCommit =
TRUE;
02858 Subsection->
u.SubsectionFlags.GlobalMemory = 1;
02859 ControlArea->
u.Flags.GlobalMemory = 1;
02860 }
02861 }
else {
02862
02863
02864
02865
02866
02867 ImageCommit =
FALSE;
02868 SectionCommit =
FALSE;
02869 }
02870
02871 NewSegment->SegmentPteTemplate = TempPte;
02872
SectorOffset = 0;
02873
02874
for (i = 0; i < Subsection->
PtesInSubsection; i += 1) {
02875
02876
02877
02878
02879
02880
if (
SectorOffset < SectionVirtualSize) {
02881
02882
02883
02884
02885
02886
if (SectionCommit) {
02887 NewSegment->NumberOfCommittedPages += 1;
02888 }
02889
if (ImageCommit) {
02890 NewSegment->ImageCommitment += 1;
02891 }
02892
02893
if (
SectorOffset < SectionTableEntry->SizeOfRawData) {
02894
02895
02896
02897
02898
MI_WRITE_INVALID_PTE (PointerPte, TempPte);
02899 }
else {
02900
02901
02902
02903
02904
MI_WRITE_INVALID_PTE (PointerPte, TempPteDemandZero);
02905 }
02906 }
else {
02907
02908
02909
02910
02911
02912
MI_WRITE_INVALID_PTE (PointerPte, ZeroPte);
02913 }
02914
SectorOffset +=
PAGE_SIZE;
02915 PointerPte += 1;
02916 NextVa +=
PAGE_SIZE;
02917 }
02918
02919
#if defined (_ALPHA_) || defined(_IA64_)
02920
}
02921
#endif
02922
02923 SectionTableEntry += 1;
02924 NumberOfSubsections -= 1;
02925 }
02926
02927
#if defined (_ALPHA_) || defined(_IA64_)
02928
if (!InvalidAlignmentAllowed) {
02929
#endif
02930
02931
02932
02933
02934
02935
ASSERT (ImageAlignment >= PAGE_SIZE);
02936 ControlArea->
NumberOfSubsections += 1;
02937
02938
02939
02940
02941
02942
02943
if (ImageFileSize > EndOfFile.LowPart) {
02944
02945
02946
02947
02948
02949 KdPrint((
"MMCREASECT: invalid image size - file size %lx - image size %lx\n %Z\n",
02950 EndOfFile.LowPart, ImageFileSize, &
File->FileName));
02951
goto BadPeImageSegment;
02952 }
02953
02954
02955
02956
02957
02958
02959
if (NumberOfPtes >= (ImageAlignment >>
PAGE_SHIFT)) {
02960
02961
02962
02963
02964
02965 KdPrint((
"MMCREASECT: invalid image - PTE left %lx\n image name %Z\n",
02966 NumberOfPtes, &
File->FileName));
02967
02968
goto BadPeImageSegment;
02969 }
02970
02971
02972
02973
02974
02975
while (NumberOfPtes != 0) {
02976
MI_WRITE_INVALID_PTE (PointerPte, ZeroPte);
02977 PointerPte += 1;
02978 NumberOfPtes -= 1;
02979 }
02980
02981
02982
02983
02984
02985
02986
if ((ExtendedHeader ==
NULL) && (SizeOfHeaders <
PAGE_SIZE)) {
02987
02988
02989
02990
02991
02992 RtlZeroMemory ((PVOID)((PCHAR)Base +
02993 SizeOfHeaders),
02994 PAGE_SIZE - SizeOfHeaders);
02995 }
02996
02997
02998
#if defined (_ALPHA_) || defined(_IA64_)
02999
}
03000
#endif
03001
03002
if (NewSegment->NumberOfCommittedPages != 0) {
03003
03004
03005
03006
03007
03008
if (
MiChargeCommitment (NewSegment->NumberOfCommittedPages, NULL) ==
FALSE) {
03009
Status = STATUS_COMMITMENT_LIMIT;
03010
ExFreePool (NewSegment);
03011
ExFreePool (ControlArea);
03012
goto NeImage;
03013 }
03014
03015
MM_TRACK_COMMIT (MM_DBG_COMMIT_IMAGE, NewSegment->NumberOfCommittedPages);
03016
Status = STATUS_SUCCESS;
03017
03018 ExAcquireFastMutex (&MmSectionCommitMutex);
03019
MmSharedCommit += NewSegment->NumberOfCommittedPages;
03020 ExReleaseFastMutex (&MmSectionCommitMutex);
03021 }
03022
03023 PeReturnSuccess:
03024
03025
03026
03027
03028
03029
03030
03031
if ((
MiHydra ==
TRUE) &&
03032 (ControlArea->
u.Flags.GlobalMemory) &&
03033 ((LoaderFlags & IMAGE_LOADER_FLAGS_SYSTEM_GLOBAL) == 0)) {
03034
03035 LargeControlArea =
ExAllocatePoolWithTag(NonPagedPool,
03036 (ULONG)(
sizeof(
LARGE_CONTROL_AREA) +
03037 (
sizeof(
SUBSECTION) *
03038 SubsectionsAllocated)),
03039 'iCmM');
03040
if (LargeControlArea ==
NULL) {
03041
03042
03043
03044
03045
03046
if (NewSegment->NumberOfCommittedPages != 0) {
03047
MiReturnCommitment (NewSegment->NumberOfCommittedPages);
03048
MM_TRACK_COMMIT (MM_DBG_COMMIT_RETURN_IMAGE_NO_LARGE_CA, NewSegment->NumberOfCommittedPages);
03049 ExAcquireFastMutex (&MmSectionCommitMutex);
03050
MmSharedCommit -= NewSegment->NumberOfCommittedPages;
03051 ExReleaseFastMutex (&MmSectionCommitMutex);
03052 }
03053
03054
ExFreePool (NewSegment);
03055
ExFreePool (ControlArea);
03056
03057
03058
Status = STATUS_INSUFFICIENT_RESOURCES;
03059
03060
goto NeImage;
03061 }
03062
03063
03064
03065
03066
03067
03068 RtlMoveMemory (LargeControlArea, ControlArea,
sizeof(CONTROL_AREA));
03069 LargeControlArea->
NonPagedPoolUsage =
EX_REAL_POOL_USAGE(
03070
sizeof(LARGE_CONTROL_AREA) +
03071 (
sizeof(
SUBSECTION) *
03072 SubsectionsAllocated));
03073
03074
ASSERT (ControlArea->
u.Flags.GlobalOnlyPerSession == 0);
03075
03076 Subsection = (
PSUBSECTION)(ControlArea + 1);
03077 NewSubsection = (
PSUBSECTION)(LargeControlArea + 1);
03078
03079
for (i = 0; i < SubsectionsAllocated; i += 1) {
03080 RtlMoveMemory (NewSubsection, Subsection,
sizeof(
SUBSECTION));
03081 NewSubsection->
ControlArea = (
PCONTROL_AREA) LargeControlArea;
03082
03083 PointerPte = NewSegment->PrototypePte;
03084
03085 TempPte.
u.Long =
MiGetSubsectionAddressForPte (NewSubsection);
03086 TempPte.
u.Soft.Prototype = 1;
03087
03088
for (j = 0; j < NewSegment->TotalNumberOfPtes; j += 1) {
03089
03090
if ((PointerPte->
u.Soft.Prototype == 1) &&
03091 (
MiGetSubsectionAddress (PointerPte) == Subsection)) {
03092 OriginalProtection =
MI_GET_PROTECTION_FROM_SOFT_PTE (PointerPte);
03093 TempPte.
u.Soft.Protection = OriginalProtection;
03094
MI_WRITE_INVALID_PTE (PointerPte, TempPte);
03095 }
03096 PointerPte += 1;
03097 }
03098
03099 Subsection += 1;
03100 NewSubsection += 1;
03101 }
03102
03103 NewSegment->
ControlArea = (
PCONTROL_AREA) LargeControlArea;
03104
03105 LargeControlArea->
u.Flags.GlobalOnlyPerSession = 1;
03106
03107 LargeControlArea->
SessionId = 0;
03108 InitializeListHead (&LargeControlArea->
UserGlobalList);
03109
03110
ExFreePool (ControlArea);
03111
03112 ControlArea = (
PCONTROL_AREA) LargeControlArea;
03113 }
03114
03115
MiUnmapImageHeaderInHyperSpace ();
03116
03117
03118
03119
03120
03121
03122 PointerPte = NewSegment->PrototypePte;
03123
03124
MiUpdateImageHeaderPage (PointerPte, PageFrameNumber, ControlArea);
03125
if (ExtendedHeader !=
NULL) {
03126
ExFreePool (ExtendedHeader);
03127 }
03128
ExFreePool (InPageEvent);
03129
03130
return STATUS_SUCCESS;
03131
03132
03133
03134
03135
03136
03137 BadPeImageSegment:
03138
03139
ExFreePool (NewSegment);
03140
ExFreePool (ControlArea);
03141
03142
03143
Status = STATUS_INVALID_IMAGE_FORMAT;
03144
03145 NeImage:
03146
MiUnmapImageHeaderInHyperSpace ();
03147
03148 BadSection:
03149
MiRemoveImageHeaderPage(PageFrameNumber);
03150
if (ExtendedHeader !=
NULL) {
03151
ExFreePool (ExtendedHeader);
03152 }
03153
ExFreePool (InPageEvent);
03154
return Status;
03155 }