00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include "mi.h"
00024
00025 ULONG
MMPPTE_NAME = 'tPmM';
00026 ULONG
MMDB = 'bDmM';
00027 extern ULONG
MMVADKEY;
00028
00029
VOID
00030
MiSetPageModified (
00031 IN PVOID Address
00032 );
00033
00034 extern LIST_ENTRY
MmLoadedUserImageList;
00035
00036 #define X256MEG (256*1024*1024)
00037
00038
#if DBG
00039
extern PEPROCESS MmWatchProcess;
00040
#endif // DBG
00041
00042 #define ROUND_TO_PAGES64(Size) (((UINT64)(Size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
00043
00044 MMSESSION MmSession;
00045
00046
NTSTATUS
00047
MiMapViewOfImageSection (
00048 IN
PCONTROL_AREA ControlArea,
00049 IN
PEPROCESS Process,
00050 IN PVOID *CapturedBase,
00051 IN PLARGE_INTEGER SectionOffset,
00052 IN PSIZE_T CapturedViewSize,
00053 IN PSECTION Section,
00054 IN SECTION_INHERIT InheritDisposition,
00055 IN ULONG_PTR ZeroBits,
00056 IN SIZE_T ImageCommitment,
00057 OUT PBOOLEAN ReleasedWsMutex
00058 );
00059
00060
NTSTATUS
00061
MiMapViewOfDataSection (
00062 IN
PCONTROL_AREA ControlArea,
00063 IN
PEPROCESS Process,
00064 IN PVOID *CapturedBase,
00065 IN PLARGE_INTEGER SectionOffset,
00066 IN PSIZE_T CapturedViewSize,
00067 IN PSECTION Section,
00068 IN SECTION_INHERIT InheritDisposition,
00069 IN ULONG ProtectionMask,
00070 IN SIZE_T CommitSize,
00071 IN ULONG_PTR ZeroBits,
00072 IN ULONG AllocationType,
00073 OUT PBOOLEAN ReleasedWsMutex
00074 );
00075
00076
VOID
00077
MiRemoveMappedPtes (
00078 IN PVOID BaseAddress,
00079 IN ULONG NumberOfPtes,
00080 IN
PCONTROL_AREA ControlArea,
00081 IN
PMMSUPPORT WorkingSetInfo
00082 );
00083
00084
NTSTATUS
00085
MiMapViewInSystemSpace (
00086 IN PVOID Section,
00087 IN
PMMSESSION Session,
00088 OUT PVOID *MappedBase,
00089 IN OUT PSIZE_T ViewSize
00090 );
00091
00092
NTSTATUS
00093
MiUnmapViewInSystemSpace (
00094 IN
PMMSESSION Session,
00095 IN PVOID MappedBase
00096 );
00097
00098 BOOLEAN
00099
MiFillSystemPageDirectory (
00100 PVOID Base,
00101 SIZE_T NumberOfBytes
00102 );
00103
00104
VOID
00105
VadTreeWalk (
00106
PMMVAD Start
00107 );
00108
00109
#if DBG
00110
VOID
00111 MiDumpConflictingVad(
00112 IN PVOID StartingAddress,
00113 IN PVOID EndingAddress,
00114 IN
PMMVAD Vad
00115 );
00116
00117
00118
VOID
00119 MiDumpConflictingVad(
00120 IN PVOID StartingAddress,
00121 IN PVOID EndingAddress,
00122 IN
PMMVAD Vad
00123 )
00124 {
00125
if (
NtGlobalFlag & FLG_SHOW_LDR_SNAPS) {
00126
DbgPrint(
"MM: [%p ... %p) conflicted with Vad %p\n",
00127 StartingAddress, EndingAddress, Vad);
00128
if ((Vad->u.VadFlags.PrivateMemory == 1) ||
00129 (Vad->ControlArea ==
NULL)) {
00130
return;
00131 }
00132
if (Vad->ControlArea->u.Flags.Image)
00133
DbgPrint(
" conflict with %Z image at [%p .. %p)\n",
00134 &Vad->ControlArea->FilePointer->FileName,
00135
MI_VPN_TO_VA (Vad->StartingVpn),
00136
MI_VPN_TO_VA_ENDING (Vad->EndingVpn)
00137 );
00138
else
00139
if (Vad->ControlArea->u.Flags.File)
00140
DbgPrint(
" conflict with %Z file at [%p .. %p)\n",
00141 &Vad->ControlArea->FilePointer->FileName,
00142
MI_VPN_TO_VA (Vad->StartingVpn),
00143
MI_VPN_TO_VA_ENDING (Vad->EndingVpn)
00144 );
00145
else
00146
DbgPrint(
" conflict with section at [%p .. %p)\n",
00147 MI_VPN_TO_VA (Vad->StartingVpn),
00148
MI_VPN_TO_VA_ENDING (Vad->EndingVpn)
00149 );
00150 }
00151 }
00152
#endif //DBG
00153
00154
00155 ULONG
00156
CacheImageSymbols(
00157 IN PVOID ImageBase
00158 );
00159
00160 PVOID
00161
MiInsertInSystemSpace (
00162 IN
PMMSESSION Session,
00163 IN ULONG SizeIn64k,
00164 IN
PCONTROL_AREA ControlArea
00165 );
00166
00167 ULONG
00168
MiRemoveFromSystemSpace (
00169 IN
PMMSESSION Session,
00170 IN PVOID Base,
00171 OUT
PCONTROL_AREA *ControlArea
00172 );
00173
00174
#ifdef ALLOC_PRAGMA
00175
#pragma alloc_text(PAGE,NtMapViewOfSection)
00176
#pragma alloc_text(PAGE,MmMapViewOfSection)
00177
#pragma alloc_text(PAGE,MmSecureVirtualMemory)
00178
#pragma alloc_text(PAGE,MmUnsecureVirtualMemory)
00179
#pragma alloc_text(PAGE,CacheImageSymbols)
00180
#pragma alloc_text(PAGE,NtAreMappedFilesTheSame)
00181
00182
#pragma alloc_text(PAGELK,MiMapViewOfPhysicalSection)
00183
#pragma alloc_text(PAGELK,MiMapViewInSystemSpace)
00184
#pragma alloc_text(PAGELK,MmMapViewInSystemSpace)
00185
#pragma alloc_text(PAGELK,MmMapViewInSessionSpace)
00186
#pragma alloc_text(PAGELK,MiUnmapViewInSystemSpace)
00187
#pragma alloc_text(PAGELK,MmUnmapViewInSystemSpace)
00188
#pragma alloc_text(PAGELK,MmUnmapViewInSessionSpace)
00189
#pragma alloc_text(PAGELK,MiFillSystemPageDirectory)
00190
#pragma alloc_text(PAGELK,MiInsertInSystemSpace)
00191
#pragma alloc_text(PAGELK,MiRemoveFromSystemSpace)
00192
00193
#pragma alloc_text(PAGEHYDRA,MiInitializeSystemSpaceMap)
00194
#pragma alloc_text(PAGEHYDRA, MiFreeSessionSpaceMap)
00195
#endif
00196
00197
00198
NTSTATUS
00199 NtMapViewOfSection(
00200 IN HANDLE SectionHandle,
00201 IN HANDLE ProcessHandle,
00202 IN OUT PVOID *BaseAddress,
00203 IN ULONG_PTR ZeroBits,
00204 IN SIZE_T CommitSize,
00205 IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
00206 IN OUT PSIZE_T ViewSize,
00207 IN SECTION_INHERIT InheritDisposition,
00208 IN ULONG AllocationType,
00209 IN ULONG Protect
00210 )
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 {
00328
PSECTION Section;
00329
PEPROCESS Process;
00330
KPROCESSOR_MODE PreviousMode;
00331
NTSTATUS Status;
00332 PVOID CapturedBase;
00333 SIZE_T CapturedViewSize;
00334 LARGE_INTEGER TempViewSize;
00335 LARGE_INTEGER CapturedOffset;
00336 ULONGLONG HighestPhysicalAddressInPfnDatabase;
00337 ACCESS_MASK DesiredSectionAccess;
00338 ULONG ProtectMaskForAccess;
00339 BOOLEAN WriteCombined;
00340
00341
PAGED_CODE();
00342
00343
00344
00345
00346
00347
#if defined (_WIN64)
00348
00349
if (ZeroBits >= 32) {
00350
00351
00352
00353
00354
00355 ZeroBits = 64 -
RtlFindMostSignificantBit (ZeroBits);
00356 }
00357
else if (ZeroBits) {
00358 ZeroBits += 32;
00359 }
00360
00361
#endif
00362
00363
if (ZeroBits >
MM_MAXIMUM_ZERO_BITS) {
00364
return STATUS_INVALID_PARAMETER_4;
00365 }
00366
00367
00368
00369
00370
00371
if ((InheritDisposition > ViewUnmap) ||
00372 (InheritDisposition < ViewShare)) {
00373
return STATUS_INVALID_PARAMETER_8;
00374 }
00375
00376
00377
00378
00379
00380
#ifdef i386
00381
00382
00383
00384
00385
00386
00387
00388
if ((AllocationType & ~(MEM_TOP_DOWN | MEM_LARGE_PAGES | MEM_DOS_LIM |
00389 SEC_NO_CHANGE | MEM_RESERVE)) != 0) {
00390
return STATUS_INVALID_PARAMETER_9;
00391 }
00392
#else
00393
if ((AllocationType & ~(MEM_TOP_DOWN | MEM_LARGE_PAGES |
00394 SEC_NO_CHANGE | MEM_RESERVE)) != 0) {
00395
return STATUS_INVALID_PARAMETER_9;
00396 }
00397
00398
#endif //i386
00399
00400
00401
00402
00403
00404
if (Protect & PAGE_WRITECOMBINE) {
00405 Protect &= ~PAGE_WRITECOMBINE;
00406 WriteCombined =
TRUE;
00407 }
00408
else {
00409 WriteCombined =
FALSE;
00410 }
00411
00412
try {
00413 ProtectMaskForAccess =
MiMakeProtectionMask (Protect) & 0x7;
00414 } except (
EXCEPTION_EXECUTE_HANDLER) {
00415
return GetExceptionCode();
00416 }
00417
00418 DesiredSectionAccess =
MmMakeSectionAccess[ProtectMaskForAccess];
00419
00420 PreviousMode = KeGetPreviousMode();
00421
00422
00423
00424
00425
00426
00427
try {
00428
if (PreviousMode !=
KernelMode) {
00429
ProbeForWritePointer ((PULONG)BaseAddress);
00430
ProbeForWriteUlong_ptr (ViewSize);
00431
00432 }
00433
00434
if (ARGUMENT_PRESENT (SectionOffset)) {
00435
if (PreviousMode !=
KernelMode) {
00436
ProbeForWrite (SectionOffset,
00437
sizeof(LARGE_INTEGER),
00438
sizeof(ULONG_PTR));
00439 }
00440 CapturedOffset = *SectionOffset;
00441 }
else {
00442
ZERO_LARGE (CapturedOffset);
00443 }
00444
00445
00446
00447
00448
00449 CapturedBase = *BaseAddress;
00450
00451
00452
00453
00454
00455 CapturedViewSize = *ViewSize;
00456
00457 } except (
ExSystemExceptionFilter()) {
00458
00459
00460
00461
00462
00463
00464
00465
return GetExceptionCode();
00466 }
00467
00468
#if DBG
00469
if (MmDebug &
MM_DBG_SHOW_NT_CALLS) {
00470
if ( !MmWatchProcess ) {
00471
DbgPrint(
"mapview process handle %lx section %lx base address %p zero bits %lx\n",
00472 ProcessHandle, SectionHandle, CapturedBase, ZeroBits);
00473
DbgPrint(
" view size %p offset %p commitsize %p protect %lx\n",
00474 CapturedViewSize, CapturedOffset, CommitSize, Protect);
00475
DbgPrint(
" Inheritdisp %lx Allocation type %lx\n",
00476 InheritDisposition, AllocationType);
00477 }
00478 }
00479
#endif
00480
00481
00482
00483
00484
00485
00486
if (CapturedBase >
MM_HIGHEST_VAD_ADDRESS) {
00487
00488
00489
00490
00491
00492
return STATUS_INVALID_PARAMETER_3;
00493 }
00494
00495
if (((ULONG_PTR)
MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)CapturedBase) <
00496 CapturedViewSize) {
00497
00498
00499
00500
00501
00502
return STATUS_INVALID_PARAMETER_3;
00503
00504 }
00505
00506
if (((ULONG_PTR)CapturedBase + CapturedViewSize) > ((ULONG_PTR)
MM_USER_ADDRESS_RANGE_LIMIT >> ZeroBits)) {
00507
00508
00509
00510
00511
00512
return STATUS_INVALID_PARAMETER_4;
00513 }
00514
00515
Status =
ObReferenceObjectByHandle ( ProcessHandle,
00516 PROCESS_VM_OPERATION,
00517
PsProcessType,
00518 PreviousMode,
00519 (PVOID *)&Process,
00520
NULL );
00521
if (!
NT_SUCCESS(
Status)) {
00522
return Status;
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
Status =
ObReferenceObjectByHandle ( SectionHandle,
00532 DesiredSectionAccess,
00533
MmSectionObjectType,
00534 PreviousMode,
00535 (PVOID *)&Section,
00536
NULL );
00537
00538
if (!
NT_SUCCESS(
Status)) {
00539
goto ErrorReturn1;
00540 }
00541
00542
if (Section->u.Flags.Image == 0) {
00543
00544
00545
00546
00547
00548
00549
if (!
MiIsProtectionCompatible (Section->InitialPageProtection,
00550 Protect)) {
00551
Status = STATUS_SECTION_PROTECTION;
00552
goto ErrorReturn;
00553 }
00554 }
00555
00556
00557
00558
00559
00560
00561
if (Section->Segment->ControlArea->u.Flags.PhysicalMemory) {
00562 HighestPhysicalAddressInPfnDatabase = (ULONGLONG)
MmHighestPhysicalPage <<
PAGE_SHIFT;
00563 CapturedOffset.LowPart = CapturedOffset.LowPart & ~(
PAGE_SIZE - 1);
00564
00565
00566
00567
00568
00569
00570
if (PreviousMode !=
KernelMode) {
00571
00572
if ((ULONGLONG)(CapturedOffset.QuadPart + CapturedViewSize) > HighestPhysicalAddressInPfnDatabase) {
00573
Status = STATUS_INVALID_PARAMETER_6;
00574
goto ErrorReturn;
00575 }
00576 }
00577
00578 }
else {
00579
00580
00581
00582
00583
00584
00585
if ((AllocationType & MEM_DOS_LIM) == 0) {
00586
if (((ULONG_PTR)CapturedBase & (
X64K - 1)) != 0) {
00587
Status = STATUS_MAPPED_ALIGNMENT;
00588
goto ErrorReturn;
00589 }
00590
00591
if ((ARGUMENT_PRESENT (SectionOffset)) &&
00592 ((CapturedOffset.LowPart & (
X64K - 1)) != 0)) {
00593
Status = STATUS_MAPPED_ALIGNMENT;
00594
goto ErrorReturn;
00595 }
00596 }
00597 }
00598
00599
00600
00601
00602
00603
00604
if ((ULONGLONG) (CapturedOffset.QuadPart + CapturedViewSize) <
00605 (ULONGLONG)CapturedOffset.QuadPart) {
00606
00607
Status = STATUS_INVALID_VIEW_SIZE;
00608
goto ErrorReturn;
00609 }
00610
00611
if (((ULONGLONG) (CapturedOffset.QuadPart + CapturedViewSize) >
00612 (ULONGLONG)Section->SizeOfSection.QuadPart) &&
00613 ((AllocationType & MEM_RESERVE) == 0)) {
00614
00615
Status = STATUS_INVALID_VIEW_SIZE;
00616
goto ErrorReturn;
00617 }
00618
00619
if (CapturedViewSize == 0) {
00620
00621
00622
00623
00624
00625 TempViewSize.QuadPart = Section->SizeOfSection.QuadPart -
00626 CapturedOffset.QuadPart;
00627
00628 CapturedViewSize = (SIZE_T)TempViewSize.QuadPart;
00629
00630
if (
00631
00632
#if !defined(_WIN64)
00633
00634 (TempViewSize.HighPart != 0) ||
00635
00636
#endif
00637
00638 (((ULONG_PTR)
MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)CapturedBase) <
00639 CapturedViewSize)) {
00640
00641
00642
00643
00644
00645
Status = STATUS_INVALID_VIEW_SIZE;
00646
goto ErrorReturn;
00647 }
00648 }
00649
00650
00651
00652
00653
00654
if ((CommitSize > CapturedViewSize) &&
00655 ((AllocationType & MEM_RESERVE) == 0)) {
00656
Status = STATUS_INVALID_PARAMETER_5;
00657
goto ErrorReturn;
00658 }
00659
00660
if (WriteCombined ==
TRUE) {
00661 Protect |= PAGE_WRITECOMBINE;
00662 }
00663
00664
Status =
MmMapViewOfSection ( (PVOID)Section,
00665 Process,
00666 &CapturedBase,
00667 ZeroBits,
00668 CommitSize,
00669 &CapturedOffset,
00670 &CapturedViewSize,
00671 InheritDisposition,
00672 AllocationType,
00673 Protect);
00674
00675
if (!
NT_SUCCESS(
Status) ) {
00676
if ( (Section->Segment->ControlArea->u.Flags.Image) &&
00677 Process ==
PsGetCurrentProcess() ) {
00678
if (
Status == STATUS_CONFLICTING_ADDRESSES ) {
00679
DbgkMapViewOfSection(
00680 SectionHandle,
00681 CapturedBase,
00682 CapturedOffset.LowPart,
00683 CapturedViewSize
00684 );
00685 }
00686 }
00687
goto ErrorReturn;
00688 }
00689
00690
00691
00692
00693
00694
00695
00696
if ( (Section->Segment->ControlArea->u.Flags.Image) &&
00697 Process ==
PsGetCurrentProcess() ) {
00698
if (
Status != STATUS_IMAGE_NOT_AT_BASE ) {
00699
DbgkMapViewOfSection(
00700 SectionHandle,
00701 CapturedBase,
00702 CapturedOffset.LowPart,
00703 CapturedViewSize
00704 );
00705 }
00706 }
00707
00708
00709
00710
00711
00712
00713
try {
00714
00715 *ViewSize = CapturedViewSize;
00716 *BaseAddress = CapturedBase;
00717
00718
if (ARGUMENT_PRESENT(SectionOffset)) {
00719 *SectionOffset = CapturedOffset;
00720 }
00721
00722 } except (
EXCEPTION_EXECUTE_HANDLER) {
00723
goto ErrorReturn;
00724 }
00725
00726
#if 0 // test code...
00727
if ((
Status == STATUS_SUCCESS) &&
00728 (Section->u.Flags.Image == 0)) {
00729
00730 PVOID Base;
00731 ULONG
Size = 0;
00732
NTSTATUS Status;
00733
00734
Status =
MmMapViewInSystemSpace ((PVOID)Section,
00735 &Base,
00736 &
Size);
00737
if (
Status == STATUS_SUCCESS) {
00738
MmUnmapViewInSystemSpace (Base);
00739 }
00740 }
00741
#endif //0
00742
00743 {
00744 ErrorReturn:
00745
ObDereferenceObject (Section);
00746 ErrorReturn1:
00747
ObDereferenceObject (Process);
00748
return Status;
00749 }
00750 }
00751
00752
NTSTATUS
00753 MmMapViewOfSection(
00754 IN PVOID SectionToMap,
00755 IN
PEPROCESS Process,
00756 IN OUT PVOID *CapturedBase,
00757 IN ULONG_PTR ZeroBits,
00758 IN SIZE_T CommitSize,
00759 IN OUT PLARGE_INTEGER SectionOffset,
00760 IN OUT PSIZE_T CapturedViewSize,
00761 IN SECTION_INHERIT InheritDisposition,
00762 IN ULONG AllocationType,
00763 IN ULONG Protect
00764 )
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851 {
00852 BOOLEAN Attached;
00853
PSECTION Section;
00854
PCONTROL_AREA ControlArea;
00855 ULONG ProtectionMask;
00856
NTSTATUS status;
00857 BOOLEAN ReleasedWsMutex;
00858 BOOLEAN WriteCombined;
00859 SIZE_T ImageCommitment;
00860
00861
PAGED_CODE();
00862
00863 Attached =
FALSE;
00864 ReleasedWsMutex =
TRUE;
00865
00866 Section = (
PSECTION)SectionToMap;
00867
00868
00869
00870
00871
00872
if ((LONGLONG)*CapturedViewSize > Section->SizeOfSection.QuadPart) {
00873
if ((AllocationType & MEM_RESERVE) == 0) {
00874
return STATUS_INVALID_VIEW_SIZE;
00875 }
00876 }
00877
00878
if (AllocationType & MEM_RESERVE) {
00879
if (((Section->InitialPageProtection & PAGE_READWRITE) |
00880 (Section->InitialPageProtection & PAGE_EXECUTE_READWRITE)) == 0) {
00881
00882
return STATUS_SECTION_PROTECTION;
00883 }
00884 }
00885
00886
if (Section->u.Flags.NoCache) {
00887 Protect |= PAGE_NOCACHE;
00888 }
00889
00890
00891
00892
00893
00894
00895
00896
if (Protect & PAGE_WRITECOMBINE) {
00897 Protect &= ~PAGE_WRITECOMBINE;
00898 WriteCombined =
TRUE;
00899 }
00900
else {
00901 WriteCombined =
FALSE;
00902 }
00903
00904
00905
00906
00907
00908
try {
00909 ProtectionMask =
MiMakeProtectionMask (Protect);
00910 } except (
EXCEPTION_EXECUTE_HANDLER) {
00911
return GetExceptionCode();
00912 }
00913
00914 ControlArea = Section->
Segment->
ControlArea;
00915 ImageCommitment = Section->
Segment->
ImageCommitment;
00916
00917
00918
00919
00920
00921
00922
if (
PsGetCurrentProcess() != Process) {
00923
KeAttachProcess (&Process->Pcb);
00924 Attached =
TRUE;
00925 }
00926
00927
00928
00929
00930
00931
00932
LOCK_ADDRESS_SPACE (Process);
00933
00934
00935
00936
00937
00938
if (Process->AddressSpaceDeleted != 0) {
00939 status = STATUS_PROCESS_IS_TERMINATING;
00940
goto ErrorReturn;
00941 }
00942
00943
00944
00945
00946
00947 ReleasedWsMutex =
FALSE;
00948
00949
if (ControlArea->
u.Flags.PhysicalMemory) {
00950
00951
MmLockPagableSectionByHandle(
ExPageLockHandle);
00952 status =
MiMapViewOfPhysicalSection (ControlArea,
00953 Process,
00954 CapturedBase,
00955 SectionOffset,
00956 CapturedViewSize,
00957 ProtectionMask,
00958 ZeroBits,
00959 AllocationType,
00960 WriteCombined,
00961 &ReleasedWsMutex);
00962
MmUnlockPagableImageSection(
ExPageLockHandle);
00963
00964 }
else if (ControlArea->
u.Flags.Image) {
00965
if (AllocationType & MEM_RESERVE) {
00966 status = STATUS_INVALID_PARAMETER_9;
00967 }
00968
else if (WriteCombined ==
TRUE) {
00969 status = STATUS_INVALID_PARAMETER_10;
00970 }
else {
00971
00972 status =
MiMapViewOfImageSection (ControlArea,
00973 Process,
00974 CapturedBase,
00975 SectionOffset,
00976 CapturedViewSize,
00977 Section,
00978 InheritDisposition,
00979 ZeroBits,
00980 ImageCommitment,
00981 &ReleasedWsMutex);
00982 }
00983
00984 }
else {
00985
00986
00987
00988
00989
00990
if (WriteCombined ==
TRUE) {
00991 status = STATUS_INVALID_PARAMETER_10;
00992 }
00993
else {
00994 status =
MiMapViewOfDataSection (ControlArea,
00995 Process,
00996 CapturedBase,
00997 SectionOffset,
00998 CapturedViewSize,
00999 Section,
01000 InheritDisposition,
01001 ProtectionMask,
01002 CommitSize,
01003 ZeroBits,
01004 AllocationType,
01005 &ReleasedWsMutex
01006 );
01007 }
01008 }
01009
01010 ErrorReturn:
01011
if (!ReleasedWsMutex) {
01012
UNLOCK_WS_AND_ADDRESS_SPACE (Process);
01013 }
01014
else {
01015
UNLOCK_ADDRESS_SPACE (Process);
01016 }
01017
01018
if (Attached) {
01019
KeDetachProcess();
01020 }
01021
01022
return status;
01023 }
01024
01025
#ifndef _ALPHA_
01026
01027
NTSTATUS
01028 MiMapViewOfPhysicalSection (
01029 IN
PCONTROL_AREA ControlArea,
01030 IN
PEPROCESS Process,
01031 IN PVOID *CapturedBase,
01032 IN PLARGE_INTEGER SectionOffset,
01033 IN PSIZE_T CapturedViewSize,
01034 IN ULONG ProtectionMask,
01035 IN ULONG_PTR ZeroBits,
01036 IN ULONG AllocationType,
01037 IN BOOLEAN WriteCombined,
01038 OUT PBOOLEAN ReleasedWsMutex
01039 )
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 {
01077
PMMVAD Vad;
01078 PVOID StartingAddress;
01079 PVOID EndingAddress;
01080 KIRQL OldIrql;
01081 KIRQL OldIrql2;
01082
PMMPTE PointerPpe;
01083
PMMPTE PointerPde;
01084
PMMPTE PointerPte;
01085
PMMPTE LastPte;
01086
MMPTE TempPte;
01087
PMMPFN Pfn2;
01088 SIZE_T PhysicalViewSize;
01089 ULONG_PTR Alignment;
01090 PVOID UsedPageTableHandle;
01091 PVOID UsedPageDirectoryHandle;
01092
PMI_PHYSICAL_VIEW PhysicalView;
01093
#ifdef LARGE_PAGES
01094
ULONG size;
01095
PMMPTE protoPte;
01096 ULONG pageSize;
01097
PSUBSECTION Subsection;
01098 ULONG EmPageSize;
01099
#endif //LARGE_PAGES
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
if (AllocationType & MEM_RESERVE) {
01119 *ReleasedWsMutex =
TRUE;
01120
return STATUS_INVALID_PARAMETER_9;
01121 }
01122 Alignment =
X64K;
01123
LOCK_WS_UNSAFE (Process);
01124
01125
#ifdef LARGE_PAGES
01126
if (AllocationType & MEM_LARGE_PAGES) {
01127
01128
01129
01130
01131
01132
if ((SectionOffset->LowPart & (
X64K - 1)) != 0) {
01133
return STATUS_INVALID_PARAMETER_9;
01134 }
01135
01136 size = (*CapturedViewSize - 1) >> (
PAGE_SHIFT + 1);
01137 pageSize =
PAGE_SIZE;
01138
01139
while (size != 0) {
01140 size = size >> 2;
01141 pageSize = pageSize << 2;
01142 }
01143
01144 Alignment = pageSize << 1;
01145
if (Alignment <
MM_VA_MAPPED_BY_PDE) {
01146 Alignment =
MM_VA_MAPPED_BY_PDE;
01147 }
01148
01149
#if defined(_IA64_)
01150
01151
01152
01153
01154
01155 EmPageSize = 0;
01156 size = pageSize - 1 ;
01157
01158
while (size) {
01159 size = size >> 1;
01160 EmPageSize += 1;
01161 }
01162
01163
if (*CapturedViewSize > pageSize) {
01164
01165
if (
MmPageSizeInfo & (pageSize << 1)) {
01166
01167
01168
01169
01170
01171 pageSize = pageSize << 1;
01172 EmPageSize += 1;
01173
01174 }
01175
else {
01176
01177 EmPageSize = EmPageSize | pageSize;
01178
01179 }
01180 }
01181
01182 pageSize = EmPageSize;
01183
#endif
01184
01185 }
01186
#endif //LARGE_PAGES
01187
01188
if (*CapturedBase ==
NULL) {
01189
01190
01191
01192
01193
01194
01195
try {
01196
01197
01198
01199
01200
#ifdef i386
01201
ASSERT (SectionOffset->HighPart == 0);
01202
#endif
01203
01204
#ifdef LARGE_PAGES
01205
if (AllocationType & MEM_LARGE_PAGES) {
01206 PhysicalViewSize = Alignment;
01207 }
else {
01208
#endif //LARGE_PAGES
01209
01210 PhysicalViewSize = *CapturedViewSize +
01211 (SectionOffset->LowPart & (
X64K - 1));
01212
#ifdef LARGE_PAGES
01213
}
01214
#endif //LARGE_PAGES
01215
01216 StartingAddress =
MiFindEmptyAddressRange (PhysicalViewSize,
01217 Alignment,
01218 (ULONG)ZeroBits);
01219
01220 } except (
EXCEPTION_EXECUTE_HANDLER) {
01221
01222
return GetExceptionCode();
01223 }
01224
01225 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress +
01226 PhysicalViewSize - 1
L) | (
PAGE_SIZE - 1
L));
01227 StartingAddress = (PVOID)((ULONG_PTR)StartingAddress +
01228 (SectionOffset->LowPart & (
X64K - 1)));
01229
01230
if (ZeroBits > 0) {
01231
if (EndingAddress > (PVOID)((ULONG_PTR)
MM_USER_ADDRESS_RANGE_LIMIT >> ZeroBits)) {
01232
return STATUS_NO_MEMORY;
01233 }
01234 }
01235
01236 }
else {
01237
01238
01239
01240
01241
01242
01243 StartingAddress = (PVOID)((ULONG_PTR)
MI_64K_ALIGN(*CapturedBase) +
01244 (SectionOffset->LowPart & (
X64K - 1)));
01245 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress +
01246 *CapturedViewSize - 1
L) | (
PAGE_SIZE - 1
L));
01247
01248
#ifdef LARGE_PAGES
01249
if (AllocationType & MEM_LARGE_PAGES) {
01250
if (((ULONG_PTR)StartingAddress & (Alignment - 1)) != 0) {
01251
return STATUS_CONFLICTING_ADDRESSES;
01252 }
01253 EndingAddress = (PVOID)((PCHAR)StartingAddress + Alignment);
01254 }
01255
#endif //LARGE_PAGES
01256
01257 Vad =
MiCheckForConflictingVad (StartingAddress, EndingAddress);
01258
01259
if (Vad != (
PMMVAD)
NULL) {
01260
#if DBG
01261
MiDumpConflictingVad (StartingAddress, EndingAddress, Vad);
01262
#endif
01263
01264
return STATUS_CONFLICTING_ADDRESSES;
01265 }
01266 }
01267
01268
01269
01270
01271
01272
01273
#ifdef LARGE_PAGES
01274
if (AllocationType & MEM_LARGE_PAGES) {
01275
01276
01277
01278
01279
01280 Subsection =
ExAllocatePoolWithTag (
NonPagedPool,
01281
sizeof(
SUBSECTION) + (4 *
sizeof(
MMPTE)),
01282
MMPPTE_NAME);
01283
if (Subsection ==
NULL) {
01284
return STATUS_INSUFFICIENT_RESOURCES;
01285 }
01286 }
01287
#endif //LARGE_PAGES
01288
01289
01290
01291
01292
01293
01294
01295
try {
01296
01297 PhysicalView = (
PMI_PHYSICAL_VIEW)
ExAllocatePoolWithTag (
NonPagedPool,
01298
sizeof(
MI_PHYSICAL_VIEW),
01299
MI_PHYSICAL_VIEW_KEY);
01300
if (PhysicalView ==
NULL) {
01301
ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
01302 }
01303
01304 Vad = (
PMMVAD)
ExAllocatePoolWithTag (
NonPagedPool,
01305
sizeof(
MMVAD),
01306
MMVADKEY);
01307
if (Vad ==
NULL) {
01308
ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
01309 }
01310
01311 PhysicalView->
Vad = Vad;
01312 PhysicalView->
StartVa = StartingAddress;
01313 PhysicalView->
EndVa = EndingAddress;
01314
01315 RtlZeroMemory (Vad,
sizeof(
MMVAD));
01316 Vad->
StartingVpn =
MI_VA_TO_VPN (StartingAddress);
01317 Vad->
EndingVpn =
MI_VA_TO_VPN (EndingAddress);
01318 Vad->
ControlArea = ControlArea;
01319 Vad->
u2.VadFlags2.Inherit =
MM_VIEW_UNMAP;
01320 Vad->
u.VadFlags.PhysicalMapping = 1;
01321 Vad->
u.VadFlags.Protection = ProtectionMask;
01322
01323
01324
01325
01326
01327
01328 Vad->
LastContiguousPte = (
PMMPTE)(ULONG)(
01329 SectionOffset->QuadPart >>
PAGE_SHIFT);
01330
#ifdef LARGE_PAGES
01331
if (AllocationType & MEM_LARGE_PAGES) {
01332 Vad->
u.VadFlags.LargePages = 1;
01333 Vad->
FirstPrototypePte = (
PMMPTE)Subsection;
01334 }
else {
01335
#endif //LARGE_PAGES
01336
01337 Vad->
FirstPrototypePte = Vad->
LastContiguousPte;
01338
#ifdef LARGE_PAGES
01339
}
01340
#endif //LARGE_PAGES
01341
01342
01343
01344
01345
01346
ASSERT (Vad->
FirstPrototypePte <= Vad->
LastContiguousPte);
01347
MiInsertVad (Vad);
01348
01349 } except (
EXCEPTION_EXECUTE_HANDLER) {
01350
01351
if (PhysicalView !=
NULL) {
01352
ExFreePool (PhysicalView);
01353 }
01354
01355
if (Vad != (
PMMVAD)
NULL) {
01356
01357
01358
01359
01360
01361
01362
01363
ExFreePool (Vad);
01364
#ifdef LARGE_PAGES
01365
if (AllocationType & MEM_LARGE_PAGES) {
01366
ExFreePool (Subsection);
01367 }
01368
#endif //LARGE_PAGES
01369
return GetExceptionCode();
01370 }
01371
return STATUS_INSUFFICIENT_RESOURCES;
01372 }
01373
01374
01375
01376
01377
01378
01379
LOCK_AWE (Process, OldIrql);
01380
LOCK_PFN2 (OldIrql2);
01381
01382 InsertHeadList (&Process->PhysicalVadList, &PhysicalView->
ListEntry);
01383
01384 ControlArea->NumberOfMappedViews += 1;
01385 ControlArea->NumberOfUserReferences += 1;
01386
01387
ASSERT (ControlArea->NumberOfSectionReferences != 0);
01388
01389
UNLOCK_PFN2 (OldIrql2);
01390
UNLOCK_AWE (Process, OldIrql);
01391
01392
01393
01394
01395
01396 PointerPpe =
MiGetPpeAddress (StartingAddress);
01397 PointerPde =
MiGetPdeAddress (StartingAddress);
01398 PointerPte =
MiGetPteAddress (StartingAddress);
01399 LastPte =
MiGetPteAddress (EndingAddress);
01400
01401
MI_MAKE_VALID_PTE (TempPte,
01402 (ULONG_PTR)Vad->
LastContiguousPte,
01403 ProtectionMask,
01404 PointerPte);
01405
01406
if (WriteCombined ==
TRUE) {
01407
MI_SET_PTE_WRITE_COMBINE (TempPte);
01408 }
01409
01410
if (TempPte.
u.Hard.Write) {
01411
MI_SET_PTE_DIRTY (TempPte);
01412 }
01413
01414
#if defined(_IA64_)
01415
if (
MI_IS_CACHING_DISABLED(&TempPte) || (WriteCombined ==
TRUE)) {
01416
KeFlushEntireTb(
FALSE,
TRUE);
01417 }
01418
#endif
01419
01420
#ifdef LARGE_PAGES
01421
if (AllocationType & MEM_LARGE_PAGES) {
01422 Subsection->
StartingSector = pageSize;
01423 Subsection->EndingSector = (ULONG_PTR)StartingAddress;
01424 Subsection->
u.LongFlags = 0;
01425 Subsection->
u.SubsectionFlags.LargePages = 1;
01426 protoPte = (
PMMPTE)(Subsection + 1);
01427
01428
01429
01430
01431
01432
01433 *protoPte = TempPte;
01434 protoPte += 1;
01435
01436
if (*CapturedViewSize > pageSize) {
01437 *protoPte = TempPte;
01438 protoPte->
u.Hard.PageFrameNumber += (pageSize >>
PAGE_SHIFT);
01439 }
else {
01440 *protoPte =
ZeroPte;
01441 }
01442 protoPte += 1;
01443
01444
01445
01446
01447
01448
01449 protoPte->
u.Long =
MiGetSubsectionAddressForPte (Subsection);
01450 protoPte->
u.Soft.Prototype = 1;
01451 protoPte->
u.Soft.Protection = ProtectionMask;
01452
01453
01454
01455
01456
01457
01458 TempPte.u.Long =
MiProtoAddressForPte (protoPte);
01459 }
01460
01461
if (!(AllocationType & MEM_LARGE_PAGES)) {
01462
#endif //LARGE_PAGES
01463
01464
#if defined (_WIN64)
01465
MiMakePpeExistAndMakeValid (PointerPpe, Process,
FALSE);
01466
if (PointerPde->
u.Long == 0) {
01467 UsedPageDirectoryHandle =
MI_GET_USED_PTES_HANDLE (PointerPte);
01468
MI_INCREMENT_USED_PTES_BY_HANDLE (UsedPageDirectoryHandle);
01469 }
01470
#endif
01471
01472
MiMakePdeExistAndMakeValid (PointerPde, Process,
FALSE);
01473
01474 Pfn2 =
MI_PFN_ELEMENT (PointerPde->
u.Hard.PageFrameNumber);
01475
01476 UsedPageTableHandle =
MI_GET_USED_PTES_HANDLE (StartingAddress);
01477
01478
while (PointerPte <= LastPte) {
01479
01480
if (
MiIsPteOnPdeBoundary (PointerPte)) {
01481
01482 PointerPde =
MiGetPteAddress (PointerPte);
01483
01484
if (
MiIsPteOnPpeBoundary (PointerPte)) {
01485 PointerPpe =
MiGetPteAddress (PointerPde);
01486
MiMakePpeExistAndMakeValid (PointerPpe, Process,
FALSE);
01487 }
01488
01489
#if defined (_WIN64)
01490
if (PointerPde->
u.Long == 0) {
01491 UsedPageDirectoryHandle =
MI_GET_USED_PTES_HANDLE (PointerPte);
01492
MI_INCREMENT_USED_PTES_BY_HANDLE (UsedPageDirectoryHandle);
01493 }
01494
#endif
01495
01496
MiMakePdeExistAndMakeValid (PointerPde, Process,
FALSE);
01497 Pfn2 =
MI_PFN_ELEMENT (PointerPde->
u.Hard.PageFrameNumber);
01498 UsedPageTableHandle =
MI_GET_USED_PTES_HANDLE (
MiGetVirtualAddressMappedByPte (PointerPte));
01499 }
01500
01501
ASSERT (PointerPte->
u.Long == 0);
01502
01503
MI_WRITE_VALID_PTE (PointerPte, TempPte);
01504
01505
CONSISTENCY_LOCK_PFN (OldIrql);
01506
01507 Pfn2->
u2.ShareCount += 1;
01508
01509
CONSISTENCY_UNLOCK_PFN (OldIrql);
01510
01511
01512
01513
01514
01515
01516
MI_INCREMENT_USED_PTES_BY_HANDLE (UsedPageTableHandle);
01517
01518 PointerPte += 1;
01519 TempPte.
u.Hard.PageFrameNumber += 1;
01520 }
01521
#ifdef LARGE_PAGES
01522
}
01523
#endif //LARGE_PAGES
01524
01525
#if defined(i386)
01526
01527
01528
01529
01530
if (WriteCombined ==
TRUE &&
MiWriteCombiningPtes ==
TRUE) {
01531
KeFlushEntireTb (
FALSE,
TRUE);
01532
KeInvalidateAllCaches (
TRUE);
01533 }
01534
#endif
01535
01536
#if defined(_IA64_)
01537
if (
MI_IS_CACHING_DISABLED(&TempPte) || (WriteCombined ==
TRUE)) {
01538
MiSweepCacheMachineDependent(StartingAddress,
01539 (PCHAR)EndingAddress - (PCHAR)StartingAddress + 1
L,
01540
MmWriteCombined);
01541 }
01542
#endif
01543
01544
UNLOCK_WS_UNSAFE (Process);
01545 *ReleasedWsMutex =
TRUE;
01546
01547
01548
01549
01550
01551 *CapturedViewSize = (PCHAR)EndingAddress - (PCHAR)StartingAddress + 1
L;
01552 Process->VirtualSize += *CapturedViewSize;
01553
01554
if (Process->VirtualSize > Process->PeakVirtualSize) {
01555 Process->PeakVirtualSize = Process->VirtualSize;
01556 }
01557
01558 *CapturedBase = StartingAddress;
01559
01560
return STATUS_SUCCESS;
01561 }
01562
01563
#endif
01564
01565
01566
NTSTATUS
01567 MiMapViewOfImageSection (
01568 IN
PCONTROL_AREA ControlArea,
01569 IN
PEPROCESS Process,
01570 IN PVOID *CapturedBase,
01571 IN PLARGE_INTEGER SectionOffset,
01572 IN PSIZE_T CapturedViewSize,
01573 IN PSECTION Section,
01574 IN SECTION_INHERIT InheritDisposition,
01575 IN ULONG_PTR ZeroBits,
01576 IN SIZE_T ImageCommitment,
01577 IN OUT PBOOLEAN ReleasedWsMutex
01578 )
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613 {
01614
PMMVAD Vad;
01615 PVOID StartingAddress;
01616 PVOID EndingAddress;
01617 BOOLEAN Attached;
01618 KIRQL OldIrql;
01619
PSUBSECTION Subsection;
01620 ULONG PteOffset;
01621
NTSTATUS ReturnedStatus;
01622
PMMPTE ProtoPte;
01623 PVOID BasedAddress;
01624 SIZE_T NeededViewSize;
01625
#if defined(_ALPHA_)
01626
ULONG_PTR Starting2gb;
01627 ULONG_PTR Ending2gb;
01628 ULONG_PTR BoundaryMask;
01629 LOGICAL AlignmentOk;
01630
#endif
01631
#if defined(_MIALT4K_)
01632
PMMPTE PointerAltPte;
01633
PMMPTE ProtoAltPte;
01634
MMPTE TempAltPte;
01635 PIMAGE_NT_HEADERS NtHeaders;
01636 ULONG ImageAlignment;
01637
#endif
01638
01639 Attached =
FALSE;
01640
01641
01642
01643
01644
01645
01646
01647
01648
if (ControlArea->u.Flags.GlobalOnlyPerSession == 0) {
01649 Subsection = (
PSUBSECTION)(ControlArea + 1);
01650 }
01651
else {
01652 Subsection = (
PSUBSECTION)((
PLARGE_CONTROL_AREA)ControlArea + 1);
01653 }
01654
01655
if (ControlArea->u.Flags.ImageMappedInSystemSpace) {
01656
01657
if (KeGetPreviousMode() !=
KernelMode) {
01658
01659
01660
01661
01662
01663
01664 *ReleasedWsMutex =
TRUE;
01665
return STATUS_CONFLICTING_ADDRESSES;
01666 }
01667 }
01668
01669
01670
01671
01672
01673
01674
01675
if (
MiCheckPurgeAndUpMapCount (ControlArea) ==
FALSE) {
01676 *ReleasedWsMutex =
TRUE;
01677
return STATUS_INSUFFICIENT_RESOURCES;
01678 }
01679
01680
01681
01682
01683
01684 BasedAddress = ControlArea->Segment->BasedAddress;
01685
01686
if (*CapturedViewSize == 0) {
01687 *CapturedViewSize =
01688 (ULONG_PTR)(Section->SizeOfSection.QuadPart - SectionOffset->QuadPart);
01689 }
01690
01691
LOCK_WS_UNSAFE (Process);
01692
01693 ReturnedStatus = STATUS_SUCCESS;
01694
01695
01696
01697
01698
01699
if (*CapturedBase !=
NULL) {
01700
01701
01702
01703
01704
01705
01706
01707
01708 Vad = (
PMMVAD)1;
01709 StartingAddress =
MI_64K_ALIGN(*CapturedBase);
01710 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress +
01711 *CapturedViewSize - 1) | (
PAGE_SIZE - 1));
01712
01713
if ((StartingAddress <=
MM_HIGHEST_VAD_ADDRESS) &&
01714 (((ULONG_PTR)
MM_HIGHEST_VAD_ADDRESS + 1) -
01715 (ULONG_PTR)StartingAddress >= *CapturedViewSize) &&
01716
01717 (EndingAddress <=
MM_HIGHEST_VAD_ADDRESS)) {
01718
01719 Vad =
MiCheckForConflictingVad (StartingAddress, EndingAddress);
01720 }
01721
01722
if (Vad !=
NULL) {
01723
#if DBG
01724
if (Vad != (
PMMVAD)1) {
01725 MiDumpConflictingVad (StartingAddress, EndingAddress, Vad);
01726 }
01727
#endif
01728
01729
LOCK_PFN (OldIrql);
01730 ControlArea->NumberOfMappedViews -= 1;
01731 ControlArea->NumberOfUserReferences -= 1;
01732
01733
01734
01735
01736
01737
01738
MiCheckControlArea (ControlArea, Process, OldIrql);
01739
return STATUS_CONFLICTING_ADDRESSES;
01740 }
01741
01742
01743
01744
01745
01746
01747
01748
if (((ULONG_PTR)StartingAddress +
01749 (ULONG_PTR)
MI_64K_ALIGN(SectionOffset->LowPart)) != (ULONG_PTR)BasedAddress) {
01750 ReturnedStatus = STATUS_IMAGE_NOT_AT_BASE;
01751 }
01752
01753 }
else {
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
if ((PVOID)*CapturedViewSize >
MM_HIGHEST_VAD_ADDRESS) {
01764
LOCK_PFN (OldIrql);
01765 ControlArea->NumberOfMappedViews -= 1;
01766 ControlArea->NumberOfUserReferences -= 1;
01767
01768
01769
01770
01771
01772
01773
MiCheckControlArea (ControlArea, Process, OldIrql);
01774
return STATUS_NO_MEMORY;
01775 }
01776
01777
01778
01779
01780
01781
01782 StartingAddress = (PVOID)((ULONG_PTR)BasedAddress +
01783 (ULONG_PTR)
MI_64K_ALIGN(SectionOffset->LowPart));
01784
01785 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress +
01786 *CapturedViewSize - 1) | (
PAGE_SIZE - 1));
01787
01788 Vad = (
PMMVAD)1;
01789 NeededViewSize = *CapturedViewSize;
01790
01791
#if defined(_ALPHA_)
01792
01793
#if defined(_AXP64_)
01794
#define BOUNDARY ((LONG_PTR)_2gb)
01795
#else
01796
#define BOUNDARY ((ULONG_PTR)_2gb)
01797
#endif
01798
01799
01800
01801
01802
01803
01804
01805 BoundaryMask = (ULONG_PTR)~(BOUNDARY-1);
01806
01807 Starting2gb = (ULONG_PTR)StartingAddress & BoundaryMask;
01808 Ending2gb = (ULONG_PTR)EndingAddress & BoundaryMask;
01809
01810 AlignmentOk =
TRUE;
01811
01812
if (Starting2gb != Ending2gb) {
01813 AlignmentOk =
FALSE;
01814
if (Starting2gb + 1 == Ending2gb) {
01815
if (((ULONG_PTR)EndingAddress & (BOUNDARY-1)) == 0) {
01816 AlignmentOk =
TRUE;
01817 }
01818 }
01819 }
01820
01821
if (AlignmentOk ==
FALSE) {
01822
01823
01824
01825
01826
01827 NeededViewSize = *CapturedViewSize * 2 +
X64K;
01828 }
01829
else
01830
#endif
01831
01832
if ((StartingAddress >= MM_LOWEST_USER_ADDRESS) &&
01833 (StartingAddress <=
MM_HIGHEST_VAD_ADDRESS) &&
01834 (((ULONG_PTR)
MM_HIGHEST_VAD_ADDRESS + 1) -
01835 (ULONG_PTR)StartingAddress >= *CapturedViewSize) &&
01836
01837 (EndingAddress <=
MM_HIGHEST_VAD_ADDRESS)) {
01838
01839 Vad =
MiCheckForConflictingVad (StartingAddress, EndingAddress);
01840 }
01841
01842
01843
01844
01845
01846
01847
if (Vad != (
PMMVAD)
NULL) {
01848
01849
01850
01851
01852
01853
#if DBG
01854
if (Vad != (
PMMVAD)1) {
01855 MiDumpConflictingVad (StartingAddress, EndingAddress, Vad);
01856 }
01857
#endif
01858
01859
01860
01861
01862
01863
01864
01865
#if defined(_X86_)
01866
01867
if ((
MmVirtualBias != 0) &&
01868 (ZeroBits == 0)) {
01869 ZeroBits = 1;
01870 }
01871
#endif
01872
01873 ReturnedStatus = STATUS_IMAGE_NOT_AT_BASE;
01874
try {
01875
01876
01877
01878
01879
01880 StartingAddress =
MiFindEmptyAddressRange (NeededViewSize,
01881
X64K,
01882 (ULONG)ZeroBits);
01883
01884
01885 } except (
EXCEPTION_EXECUTE_HANDLER) {
01886
LOCK_PFN (OldIrql);
01887 ControlArea->NumberOfMappedViews -= 1;
01888 ControlArea->NumberOfUserReferences -= 1;
01889
01890
01891
01892
01893
01894
01895
MiCheckControlArea (ControlArea, Process, OldIrql);
01896
01897
return GetExceptionCode();
01898 }
01899
01900 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress +
01901 *CapturedViewSize - 1) | (
PAGE_SIZE - 1));
01902
01903
#if defined(_ALPHA_)
01904
01905
if (AlignmentOk ==
FALSE) {
01906 Starting2gb = (ULONG_PTR)StartingAddress & ~(BOUNDARY-1);
01907 Ending2gb = (ULONG_PTR)EndingAddress & ~(BOUNDARY-1);
01908
01909
if (Starting2gb != Ending2gb) {
01910
01911
01912
01913
01914
01915 StartingAddress = (PVOID)Ending2gb;
01916 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress +
01917 *CapturedViewSize - 1) | (
PAGE_SIZE - 1));
01918 }
01919 }
01920
#endif
01921
01922 }
01923 }
01924
01925
01926
01927
01928
01929 Vad =
ExAllocatePoolWithTag (
NonPagedPool,
sizeof(
MMVAD),
MMVADKEY);
01930
try {
01931
if (Vad ==
NULL) {
01932
ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
01933 }
01934
01935 RtlZeroMemory (Vad,
sizeof(
MMVAD));
01936 Vad->
StartingVpn =
MI_VA_TO_VPN (StartingAddress);
01937 Vad->
EndingVpn =
MI_VA_TO_VPN (EndingAddress);
01938 Vad->
u2.VadFlags2.Inherit = (InheritDisposition == ViewShare);
01939 Vad->
u.VadFlags.ImageMap = 1;
01940
01941
01942
01943
01944
01945 Vad->
u.VadFlags.Protection =
MM_EXECUTE_WRITECOPY;
01946 Vad->
ControlArea = ControlArea;
01947
01948
01949
01950
01951
01952 SectionOffset->LowPart = SectionOffset->LowPart & ~(
X64K - 1);
01953 PteOffset = (ULONG)(SectionOffset->QuadPart >>
PAGE_SHIFT);
01954
01955 Vad->
FirstPrototypePte = &Subsection->
SubsectionBase[PteOffset];
01956 Vad->
LastContiguousPte =
MM_ALLOCATION_FILLS_VAD;
01957
01958
01959
01960
01961
01962
01963
01964
01965 Vad->
u.VadFlags.CommitCharge = (SIZE_T)ImageCommitment;
01966
01967
ASSERT (Vad->
FirstPrototypePte <= Vad->
LastContiguousPte);
01968
01969
MiInsertVad (Vad);
01970
01971 } except (
EXCEPTION_EXECUTE_HANDLER) {
01972
LOCK_PFN (OldIrql);
01973 ControlArea->NumberOfMappedViews -= 1;
01974 ControlArea->NumberOfUserReferences -= 1;
01975
01976
01977
01978
01979
01980
01981
MiCheckControlArea (ControlArea, Process, OldIrql);
01982
01983
if (Vad != (
PMMVAD)
NULL) {
01984
01985
01986
01987
01988
01989
01990
01991
ExFreePool (Vad);
01992
return GetExceptionCode();
01993 }
01994
01995
return STATUS_INSUFFICIENT_RESOURCES;
01996 }
01997
01998 *CapturedViewSize = (PCHAR)EndingAddress - (PCHAR)StartingAddress + 1
L;
01999 *CapturedBase = StartingAddress;
02000
02001
#if DBG
02002
if (MmDebug &
MM_DBG_WALK_VAD_TREE) {
02003
DbgPrint(
"mapped image section vads\n");
02004
VadTreeWalk(Process->VadRoot);
02005 }
02006
#endif
02007
02008
02009
02010
02011
02012 Process->VirtualSize += *CapturedViewSize;
02013
02014
if (Process->VirtualSize > Process->PeakVirtualSize) {
02015 Process->PeakVirtualSize = Process->VirtualSize;
02016 }
02017
02018
if (ControlArea->u.Flags.FloppyMedia) {
02019
02020 *ReleasedWsMutex =
TRUE;
02021
UNLOCK_WS_UNSAFE (Process);
02022
02023
02024
02025
02026
02027
02028
02029
02030 ProtoPte = Vad->
FirstPrototypePte;
02031
02032
02033
02034
02035
02036
while (StartingAddress < EndingAddress) {
02037
02038
02039
02040
02041
02042
02043
02044
if ((ProtoPte->
u.Hard.Valid == 1) ||
02045 (ProtoPte->
u.Soft.Prototype == 1) ||
02046 (ProtoPte->
u.Soft.Transition == 1)) {
02047
02048
try {
02049
02050
MiSetPageModified (StartingAddress);
02051
02052 } except (
EXCEPTION_EXECUTE_HANDLER) {
02053
02054
02055
02056
02057
02058
02059 NOTHING;
02060 }
02061 }
02062 ProtoPte += 1;
02063 StartingAddress = (PVOID)((PCHAR)StartingAddress +
PAGE_SIZE);
02064 }
02065 }
02066
02067
if (!*ReleasedWsMutex) {
02068 *ReleasedWsMutex =
TRUE;
02069
UNLOCK_WS_UNSAFE (Process);
02070 }
02071
02072
if (
NT_SUCCESS(ReturnedStatus)) {
02073
02074
02075
02076
02077
02078
02079
02080
if (ControlArea->Segment->ImageInformation->ImageContainsCode &&
02081 ((ControlArea->Segment->ImageInformation->Machine <
02082 USER_SHARED_DATA->ImageNumberLow) ||
02083 (ControlArea->Segment->ImageInformation->Machine >
02084 USER_SHARED_DATA->ImageNumberHigh)
02085 )
02086 ) {
02087
#if defined (_WIN64)
02088
02089
02090
02091
02092
02093
if (!Process->Wow64Process ||
02094 ControlArea->Segment->ImageInformation->Machine != IMAGE_FILE_MACHINE_I386) {
02095
return STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
02096 }
02097
#else
02098
return STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
02099
#endif
02100
}
02101
02102 StartingAddress =
MI_VPN_TO_VA (Vad->
StartingVpn);
02103
02104
if (
PsImageNotifyEnabled) {
02105
02106
IMAGE_INFO ImageInfo;
02107
02108
if ( (StartingAddress <
MmHighestUserAddress) &&
02109 Process->UniqueProcessId &&
02110 Process !=
PsInitialSystemProcess ) {
02111
02112 ImageInfo.
Properties = 0;
02113 ImageInfo.
ImageAddressingMode =
IMAGE_ADDRESSING_MODE_32BIT;
02114 ImageInfo.
ImageBase = StartingAddress;
02115 ImageInfo.
ImageSize = *CapturedViewSize;
02116 ImageInfo.
ImageSelector = 0;
02117 ImageInfo.
ImageSectionNumber = 0;
02118
PsCallImageNotifyRoutines(
02119 (PUNICODE_STRING) &ControlArea->FilePointer->FileName,
02120 Process->UniqueProcessId,
02121 &ImageInfo
02122 );
02123 }
02124 }
02125
02126
if ((
NtGlobalFlag & FLG_ENABLE_KDEBUG_SYMBOL_LOAD) &&
02127 (ControlArea->u.Flags.Image) &&
02128 (ReturnedStatus != STATUS_IMAGE_NOT_AT_BASE)) {
02129
if (ControlArea->u.Flags.DebugSymbolsLoaded == 0) {
02130
if (
CacheImageSymbols (StartingAddress)) {
02131
02132
02133
02134
02135
02136 PUNICODE_STRING
FileName;
02137 ANSI_STRING AnsiName;
02138
NTSTATUS Status;
02139
02140
LOCK_PFN (OldIrql);
02141 ControlArea->u.Flags.DebugSymbolsLoaded = 1;
02142
UNLOCK_PFN (OldIrql);
02143
02144
FileName = (PUNICODE_STRING)&ControlArea->FilePointer->FileName;
02145
if (
FileName->Length != 0 && (
NtGlobalFlag & FLG_ENABLE_KDEBUG_SYMBOL_LOAD)) {
02146 PLIST_ENTRY Head, Next;
02147 PLDR_DATA_TABLE_ENTRY Entry;
02148
02149
KeEnterCriticalRegion();
02150
ExAcquireResourceExclusive (&
PsLoadedModuleResource,
TRUE);
02151 Head = &
MmLoadedUserImageList;
02152 Next = Head->Flink;
02153
while (Next != Head) {
02154 Entry = CONTAINING_RECORD( Next,
02155 LDR_DATA_TABLE_ENTRY,
02156 InLoadOrderLinks
02157 );
02158
if (Entry->DllBase == StartingAddress) {
02159 Entry->LoadCount += 1;
02160
break;
02161 }
02162 Next = Next->Flink;
02163 }
02164
02165
if (Next == Head) {
02166 Entry =
ExAllocatePoolWithTag(
NonPagedPool,
02167
sizeof( *Entry ) +
02168
FileName->Length +
02169
sizeof( UNICODE_NULL ),
02170
MMDB
02171 );
02172
if (Entry !=
NULL) {
02173 PIMAGE_NT_HEADERS NtHeaders;
02174
02175 RtlZeroMemory (Entry,
sizeof(*Entry));
02176
02177
try {
02178 NtHeaders =
RtlImageNtHeader (StartingAddress);
02179
if (NtHeaders !=
NULL) {
02180
#if defined(_WIN64)
02181
if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
02182 Entry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
02183 Entry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
02184 }
02185
else {
02186 PIMAGE_NT_HEADERS32 NtHeaders32 = (PIMAGE_NT_HEADERS32)NtHeaders;
02187
02188 Entry->SizeOfImage = NtHeaders32->OptionalHeader.SizeOfImage;
02189 Entry->CheckSum = NtHeaders32->OptionalHeader.CheckSum;
02190 }
02191
#else
02192
Entry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
02193 Entry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
02194
#endif
02195
}
02196 } except (
EXCEPTION_EXECUTE_HANDLER) {
02197 NOTHING;
02198 }
02199
02200 Entry->DllBase = StartingAddress;
02201 Entry->FullDllName.Buffer = (PWSTR)(Entry+1);
02202 Entry->FullDllName.Length =
FileName->Length;
02203 Entry->FullDllName.MaximumLength = (
USHORT)
02204 (Entry->FullDllName.Length +
sizeof( UNICODE_NULL ));
02205 RtlMoveMemory( Entry->FullDllName.Buffer,
02206
FileName->Buffer,
02207
FileName->Length
02208 );
02209 Entry->FullDllName.Buffer[ Entry->FullDllName.Length /
sizeof( WCHAR )] = UNICODE_NULL;
02210 Entry->LoadCount = 1;
02211 InsertTailList( &
MmLoadedUserImageList,
02212 &Entry->InLoadOrderLinks
02213 );
02214 InitializeListHead( &Entry->InInitializationOrderLinks );
02215 InitializeListHead( &Entry->InMemoryOrderLinks );
02216 }
02217 }
02218
02219
ExReleaseResource (&
PsLoadedModuleResource);
02220
KeLeaveCriticalRegion();
02221 }
02222
02223
Status =
RtlUnicodeStringToAnsiString( &AnsiName,
02224
FileName,
02225
TRUE );
02226
02227
if (
NT_SUCCESS(
Status)) {
02228 DbgLoadImageSymbols( &AnsiName,
02229 StartingAddress,
02230 (ULONG_PTR)Process
02231 );
02232
RtlFreeAnsiString( &AnsiName );
02233 }
02234 }
02235 }
02236 }
02237 }
02238
02239
#if defined(_MIALT4K_)
02240
02241
if (Process->Wow64Process !=
NULL) {
02242
02243
MiProtectImageFileFor4kPage(StartingAddress,
02244 *CapturedViewSize,
02245 Vad->
FirstPrototypePte,
02246 Process);
02247 }
02248
02249
#endif
02250
02251
return ReturnedStatus;
02252
02253 }
02254
02255
NTSTATUS
02256 MiMapViewOfDataSection (
02257 IN
PCONTROL_AREA ControlArea,
02258 IN
PEPROCESS Process,
02259 IN PVOID *CapturedBase,
02260 IN PLARGE_INTEGER SectionOffset,
02261 IN PSIZE_T CapturedViewSize,
02262 IN PSECTION Section,
02263 IN SECTION_INHERIT InheritDisposition,
02264 IN ULONG ProtectionMask,
02265 IN SIZE_T CommitSize,
02266 IN ULONG_PTR ZeroBits,
02267 IN ULONG AllocationType,
02268 IN PBOOLEAN ReleasedWsMutex
02269 )
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306 {
02307
PMMVAD Vad;
02308 PVOID StartingAddress;
02309 PVOID EndingAddress;
02310 BOOLEAN Attached;
02311 KIRQL OldIrql;
02312
PSUBSECTION Subsection;
02313 ULONG PteOffset;
02314
PMMPTE PointerPte;
02315
PMMPTE LastPte;
02316
MMPTE TempPte;
02317 ULONG_PTR Alignment;
02318 SIZE_T QuotaCharge;
02319 BOOLEAN ChargedQuota;
02320
PMMPTE TheFirstPrototypePte;
02321 PVOID CapturedStartingVa;
02322 ULONG CapturedCopyOnWrite;
02323
#if defined(_MIALT4K_)
02324
SIZE_T ViewSizeFor4k;
02325
#endif
02326
02327 Attached =
FALSE;
02328 QuotaCharge = 0;
02329 ChargedQuota =
FALSE;
02330
02331
if ((AllocationType & MEM_RESERVE) &&
02332 (ControlArea->FilePointer ==
NULL)) {
02333 *ReleasedWsMutex =
TRUE;
02334
return STATUS_INVALID_PARAMETER_9;
02335 }
02336
02337
02338
02339
02340
02341
02342
if ((AllocationType & MEM_DOS_LIM) != 0) {
02343
if ((*CapturedBase ==
NULL) ||
02344 (AllocationType & MEM_RESERVE)) {
02345
02346
02347
02348
02349
02350
02351 *ReleasedWsMutex =
TRUE;
02352
return STATUS_INVALID_PARAMETER_3;
02353 }
02354 Alignment =
PAGE_SIZE;
02355 }
else {
02356 Alignment =
X64K;
02357 }
02358
02359
02360
02361
02362
02363
02364
02365
if (
MiCheckPurgeAndUpMapCount (ControlArea) ==
FALSE) {
02366 *ReleasedWsMutex =
TRUE;
02367
return STATUS_INSUFFICIENT_RESOURCES;
02368 }
02369
02370
if (*CapturedViewSize == 0) {
02371
02372 SectionOffset->LowPart = SectionOffset->LowPart & ~((ULONG)Alignment - 1);
02373 *CapturedViewSize = (ULONG_PTR)(Section->SizeOfSection.QuadPart -
02374 SectionOffset->QuadPart);
02375 }
else {
02376 *CapturedViewSize += SectionOffset->LowPart & (Alignment - 1);
02377 SectionOffset->LowPart = SectionOffset->LowPart & ~((ULONG)Alignment - 1);
02378 }
02379
02380
if ((LONG_PTR)*CapturedViewSize <= 0) {
02381
02382
02383
02384
02385
02386
LOCK_PFN (OldIrql);
02387 ControlArea->NumberOfMappedViews -= 1;
02388 ControlArea->NumberOfUserReferences -= 1;
02389
02390
02391
02392
02393
02394
02395
MiCheckControlArea (ControlArea,
NULL, OldIrql);
02396
02397 *ReleasedWsMutex =
TRUE;
02398
return STATUS_INVALID_VIEW_SIZE;
02399 }
02400
02401
02402
02403
02404
02405
ASSERT (ControlArea->u.Flags.GlobalOnlyPerSession == 0);
02406
02407 Subsection = (
PSUBSECTION)(ControlArea + 1);
02408
02409 SectionOffset->LowPart = SectionOffset->LowPart & ~((ULONG)Alignment - 1);
02410 PteOffset = (ULONG)(SectionOffset->QuadPart >>
PAGE_SHIFT);
02411
02412
02413
02414
02415
02416
02417
if (PteOffset >= ControlArea->Segment->TotalNumberOfPtes) {
02418
LOCK_PFN (OldIrql);
02419 ControlArea->NumberOfMappedViews -= 1;
02420 ControlArea->NumberOfUserReferences -= 1;
02421
02422
02423
02424
02425
02426
02427
MiCheckControlArea (ControlArea,
NULL, OldIrql);
02428
02429 *ReleasedWsMutex =
TRUE;
02430
return STATUS_INVALID_VIEW_SIZE;
02431 }
02432
02433
while (PteOffset >= Subsection->
PtesInSubsection) {
02434 PteOffset -= Subsection->
PtesInSubsection;
02435 Subsection = Subsection->
NextSubsection;
02436
ASSERT (Subsection !=
NULL);
02437 }
02438
02439 TheFirstPrototypePte = &Subsection->
SubsectionBase[PteOffset];
02440
02441
02442
02443
02444
02445
if ((ControlArea->FilePointer ==
NULL) &&
02446 (CommitSize != 0) &&
02447 (ControlArea->Segment->NumberOfCommittedPages <
02448 ControlArea->Segment->TotalNumberOfPtes)) {
02449
02450
02451
ExAcquireFastMutexUnsafe (&
MmSectionCommitMutex);
02452
02453 PointerPte = TheFirstPrototypePte;
02454 LastPte = PointerPte +
BYTES_TO_PAGES(CommitSize);
02455
02456
while (PointerPte < LastPte) {
02457
if (PointerPte->
u.Long == 0) {
02458 QuotaCharge += 1;
02459 }
02460 PointerPte += 1;
02461 }
02462
ExReleaseFastMutexUnsafe (&
MmSectionCommitMutex);
02463 }
02464
02465 CapturedStartingVa = (PVOID)Section->Address.StartingVpn;
02466 CapturedCopyOnWrite = Section->u.Flags.CopyOnWrite;
02467
LOCK_WS_UNSAFE (Process);
02468
02469
if ((*CapturedBase ==
NULL) && (CapturedStartingVa ==
NULL)) {
02470
02471
02472
02473
02474
02475
try {
02476
02477
02478
02479
02480
02481
if ( AllocationType & MEM_TOP_DOWN ) {
02482 StartingAddress =
MiFindEmptyAddressRangeDown (
02483 *CapturedViewSize,
02484 (PVOID)((PCHAR)
MM_HIGHEST_VAD_ADDRESS + 1),
02485 Alignment
02486 );
02487 }
else {
02488 StartingAddress =
MiFindEmptyAddressRange (*CapturedViewSize,
02489 Alignment,
02490 (ULONG)ZeroBits);
02491 }
02492
02493 } except (
EXCEPTION_EXECUTE_HANDLER) {
02494
02495
LOCK_PFN (OldIrql);
02496 ControlArea->NumberOfMappedViews -= 1;
02497 ControlArea->NumberOfUserReferences -= 1;
02498
02499
02500
02501
02502
02503
02504
MiCheckControlArea (ControlArea, Process, OldIrql);
02505
02506
return GetExceptionCode();
02507 }
02508
02509 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress +
02510 *CapturedViewSize - 1
L) | (
PAGE_SIZE - 1
L));
02511
02512
if (ZeroBits > 0) {
02513
if (EndingAddress > (PVOID)((ULONG_PTR)
MM_USER_ADDRESS_RANGE_LIMIT >> ZeroBits)) {
02514
LOCK_PFN (OldIrql);
02515 ControlArea->NumberOfMappedViews -= 1;
02516 ControlArea->NumberOfUserReferences -= 1;
02517
02518
02519
02520
02521
02522
02523
MiCheckControlArea (ControlArea, Process, OldIrql);
02524
02525
return STATUS_NO_MEMORY;
02526 }
02527 }
02528
02529 }
else {
02530
02531
if (*CapturedBase ==
NULL) {
02532
02533
02534
02535
02536
02537 StartingAddress = (PVOID)((PCHAR)CapturedStartingVa +
02538 SectionOffset->LowPart);
02539 }
else {
02540
02541 StartingAddress =
MI_ALIGN_TO_SIZE (*CapturedBase, Alignment);
02542
02543 }
02544
02545
02546
02547
02548
02549
02550 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress +
02551 *CapturedViewSize - 1
L) | (
PAGE_SIZE - 1
L));
02552
02553 Vad =
MiCheckForConflictingVad (StartingAddress, EndingAddress);
02554
if (Vad != (
PMMVAD)
NULL) {
02555
#if DBG
02556
MiDumpConflictingVad (StartingAddress, EndingAddress, Vad);
02557
#endif
02558
02559
LOCK_PFN (OldIrql);
02560 ControlArea->NumberOfMappedViews -= 1;
02561 ControlArea->NumberOfUserReferences -= 1;
02562
02563
02564
02565
02566
02567
02568
MiCheckControlArea (ControlArea, Process, OldIrql);
02569
02570
return STATUS_CONFLICTING_ADDRESSES;
02571 }
02572 }
02573
02574
02575
02576
02577
02578
02579
try {
02580
02581 Vad =
ExAllocatePoolWithTag (
NonPagedPool,
02582
sizeof(
MMVAD),
02583
MMVADKEY);
02584
if (Vad ==
NULL) {
02585
ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
02586 }
02587 RtlZeroMemory (Vad,
sizeof(
MMVAD));
02588
02589 Vad->
StartingVpn =
MI_VA_TO_VPN (StartingAddress);
02590 Vad->
EndingVpn =
MI_VA_TO_VPN (EndingAddress);
02591 Vad->
FirstPrototypePte = TheFirstPrototypePte;
02592
02593
02594
02595
02596
02597 Vad->
ControlArea = ControlArea;
02598
02599 Vad->
u2.VadFlags2.Inherit = (InheritDisposition == ViewShare);
02600 Vad->
u.VadFlags.Protection = ProtectionMask;
02601 Vad->
u2.VadFlags2.CopyOnWrite = CapturedCopyOnWrite;
02602
02603
02604
02605
02606
02607
02608 Vad->
u2.VadFlags2.FileOffset = (ULONG)(SectionOffset->QuadPart >> 16);
02609
02610
if ((AllocationType & SEC_NO_CHANGE) || (Section->u.Flags.NoChange)) {
02611 Vad->
u.VadFlags.NoChange = 1;
02612 Vad->
u2.VadFlags2.SecNoChange = 1;
02613 }
02614
if (AllocationType & MEM_RESERVE) {
02615
PMMEXTEND_INFO ExtendInfo;
02616
02617
ExAcquireFastMutexUnsafe (&
MmSectionBasedMutex);
02618 ExtendInfo = ControlArea->Segment->ExtendInfo;
02619
if (ExtendInfo) {
02620 ExtendInfo->
ReferenceCount += 1;
02621
if (ExtendInfo->
CommittedSize < (UINT64)Section->SizeOfSection.QuadPart) {
02622 ExtendInfo->
CommittedSize = (UINT64)Section->SizeOfSection.QuadPart;
02623 }
02624 }
else {
02625
02626 ExtendInfo =
ExAllocatePoolWithTag (
NonPagedPool,
02627
sizeof(
MMEXTEND_INFO),
02628 'xCmM');
02629
if (ExtendInfo ==
NULL) {
02630
ExReleaseFastMutexUnsafe (&
MmSectionBasedMutex);
02631
ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
02632 }
02633 ExtendInfo->
ReferenceCount = 1;
02634 ExtendInfo->
CommittedSize = ControlArea->Segment->SizeOfSegment;
02635
if (ExtendInfo->
CommittedSize < (UINT64)Section->SizeOfSection.QuadPart) {
02636 ExtendInfo->
CommittedSize = (UINT64)Section->SizeOfSection.QuadPart;
02637 }
02638 ControlArea->Segment->ExtendInfo = ExtendInfo;
02639 }
02640
ExReleaseFastMutexUnsafe (&
MmSectionBasedMutex);
02641 Vad->
u2.VadFlags2.ExtendableFile = 1;
02642
ASSERT (Vad->
u4.ExtendedInfo ==
NULL);
02643 Vad->
u4.ExtendedInfo = ExtendInfo;
02644 }
02645
02646
02647
02648
02649
02650
02651
if (
MI_IS_PTE_PROTECTION_COPY_WRITE(ProtectionMask)) {
02652 Vad->
u.VadFlags.CommitCharge = (
BYTES_TO_PAGES ((PCHAR) EndingAddress -
02653 (PCHAR) StartingAddress));
02654 }
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
#if 0
02668
if (ControlArea->FilePointer ==
NULL) {
02669
02670
02671
02672
02673
02674 Vad->CommitCharge += (
BYTES_TO_PAGES ((PCHAR)EndingAddress -
02675 (PCHAR)StartingAddress));
02676 }
02677
#endif
02678
02679
02680 PteOffset += (ULONG)(Vad->
EndingVpn - Vad->
StartingVpn);
02681
02682
if (PteOffset < Subsection->
PtesInSubsection ) {
02683 Vad->
LastContiguousPte = &Subsection->
SubsectionBase[PteOffset];
02684
02685 }
else {
02686 Vad->
LastContiguousPte = &Subsection->
SubsectionBase[
02687 (Subsection->
PtesInSubsection - 1) +
02688 Subsection->
UnusedPtes];
02689 }
02690
02691
if (QuotaCharge != 0) {
02692
if (
MiChargeCommitment (QuotaCharge, Process) ==
FALSE) {
02693
ExRaiseStatus (STATUS_COMMITMENT_LIMIT);
02694 }
02695 ChargedQuota =
TRUE;
02696
MM_TRACK_COMMIT (
MM_DBG_COMMIT_MAPVIEW_DATA, QuotaCharge);
02697 }
02698
02699
ASSERT (Vad->
FirstPrototypePte <= Vad->
LastContiguousPte);
02700
MiInsertVad (Vad);
02701
02702 } except (
EXCEPTION_EXECUTE_HANDLER) {
02703
02704
LOCK_PFN (OldIrql);
02705 ControlArea->NumberOfMappedViews -= 1;
02706 ControlArea->NumberOfUserReferences -= 1;
02707
02708
02709
02710
02711
02712
02713
MiCheckControlArea (ControlArea, Process, OldIrql);
02714
02715
if (Vad != (
PMMVAD)
NULL) {
02716
02717
02718
02719
02720
02721
02722
02723
ExFreePool (Vad);
02724
if (ChargedQuota) {
02725
MiReturnCommitment (QuotaCharge);
02726
MM_TRACK_COMMIT (
MM_DBG_COMMIT_RETURN_MAPVIEW_DATA, QuotaCharge);
02727 }
02728
return GetExceptionCode();
02729 }
02730
return STATUS_INSUFFICIENT_RESOURCES;
02731 }
02732
02733 *ReleasedWsMutex =
TRUE;
02734
02735
#if DBG
02736
if (!(AllocationType & MEM_RESERVE)) {
02737
ASSERT(((ULONG_PTR)EndingAddress - (ULONG_PTR)StartingAddress) <=
02738
ROUND_TO_PAGES64(Section->Segment->SizeOfSegment));
02739 }
02740
#endif //DBG
02741
02742
UNLOCK_WS_UNSAFE (Process);
02743
02744
02745
02746
02747
02748
if (QuotaCharge != 0) {
02749
02750
ExAcquireFastMutexUnsafe (&
MmSectionCommitMutex);
02751
02752 PointerPte = Vad->
FirstPrototypePte;
02753 LastPte = PointerPte +
BYTES_TO_PAGES(CommitSize);
02754 TempPte = ControlArea->Segment->SegmentPteTemplate;
02755
02756
while (PointerPte < LastPte) {
02757
02758
if (PointerPte->
u.Long == 0) {
02759
02760
MI_WRITE_INVALID_PTE (PointerPte, TempPte);
02761 }
02762 PointerPte += 1;
02763 }
02764
02765 ControlArea->Segment->NumberOfCommittedPages += QuotaCharge;
02766
02767
ASSERT (ControlArea->Segment->NumberOfCommittedPages <=
02768 ControlArea->Segment->TotalNumberOfPtes);
02769
MmSharedCommit += QuotaCharge;
02770
02771
ExReleaseFastMutexUnsafe (&
MmSectionCommitMutex);
02772 }
02773
02774
#if defined(_MIALT4K_)
02775
02776
if (Process->Wow64Process !=
NULL) {
02777
02778
02779 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress +
02780 *CapturedViewSize - 1
L) | (
PAGE_4K - 1
L));
02781
02782 ViewSizeFor4k = (PCHAR)EndingAddress - (PCHAR)StartingAddress + 1
L;
02783
02784
MiProtectMapFileFor4kPage (StartingAddress,
02785 ViewSizeFor4k,
02786 ProtectionMask,
02787 Vad->
FirstPrototypePte,
02788 Process);
02789 }
02790
#endif
02791
02792
02793
02794
02795
02796 *CapturedViewSize = (PCHAR)EndingAddress - (PCHAR)StartingAddress + 1
L;
02797 Process->VirtualSize += *CapturedViewSize;
02798
02799
if (Process->VirtualSize > Process->PeakVirtualSize) {
02800 Process->PeakVirtualSize = Process->VirtualSize;
02801 }
02802
02803 *CapturedBase = StartingAddress;
02804
02805
return STATUS_SUCCESS;
02806 }
02807
02808 LOGICAL
02809 MiCheckPurgeAndUpMapCount (
02810 IN
PCONTROL_AREA ControlArea
02811 )
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841 {
02842 KIRQL OldIrql;
02843
PEVENT_COUNTER PurgedEvent;
02844
PEVENT_COUNTER WaitEvent;
02845 ULONG OldRef;
02846
02847 PurgedEvent =
NULL;
02848 OldRef = 1;
02849
02850
LOCK_PFN (OldIrql);
02851
02852
while (ControlArea->u.Flags.BeingPurged != 0) {
02853
02854
02855
02856
02857
02858
if (PurgedEvent ==
NULL) {
02859
02860
02861
02862
02863
02864 PurgedEvent =
MiGetEventCounter ();
02865
if (PurgedEvent ==
NULL) {
02866
UNLOCK_PFN (OldIrql);
02867
return FALSE;
02868 }
02869
02870
continue;
02871 }
02872
02873
if (ControlArea->WaitingForDeletion ==
NULL) {
02874 ControlArea->WaitingForDeletion = PurgedEvent;
02875 WaitEvent = PurgedEvent;
02876 PurgedEvent =
NULL;
02877 }
else {
02878 WaitEvent = ControlArea->WaitingForDeletion;
02879 WaitEvent->
RefCount += 1;
02880 }
02881
02882
02883
02884
02885
02886
KeEnterCriticalRegion();
02887
UNLOCK_PFN_AND_THEN_WAIT(OldIrql);
02888
02889
KeWaitForSingleObject(&WaitEvent->
Event,
02890
WrVirtualMemory,
02891
KernelMode,
02892
FALSE,
02893 (PLARGE_INTEGER)
NULL);
02894
LOCK_PFN (OldIrql);
02895
KeLeaveCriticalRegion();
02896
MiFreeEventCounter (WaitEvent,
FALSE);
02897 }
02898
02899
02900
02901
02902
02903 ControlArea->NumberOfMappedViews += 1;
02904 ControlArea->NumberOfUserReferences += 1;
02905 ControlArea->u.Flags.HadUserReference = 1;
02906
ASSERT (ControlArea->NumberOfSectionReferences != 0);
02907
02908
if (PurgedEvent !=
NULL) {
02909
MiFreeEventCounter (PurgedEvent,
TRUE);
02910 }
02911
UNLOCK_PFN (OldIrql);
02912
02913
return TRUE;
02914 }
02915
02916 typedef struct _NTSYM {
02917 struct _NTSYM *
Next;
02918 PVOID
SymbolTable;
02919 ULONG
NumberOfSymbols;
02920 PVOID
StringTable;
02921 USHORT Flags;
02922 USHORT EntrySize;
02923 ULONG
MinimumVa;
02924 ULONG
MaximumVa;
02925 PCHAR
MapName;
02926 ULONG
MapNameLen;
02927 }
NTSYM, *
PNTSYM;
02928
02929 ULONG
02930 CacheImageSymbols(
02931 IN PVOID ImageBase
02932 )
02933 {
02934 PIMAGE_DEBUG_DIRECTORY DebugDirectory;
02935 ULONG DebugSize;
02936
02937
PAGED_CODE();
02938
02939
try {
02940 DebugDirectory = (PIMAGE_DEBUG_DIRECTORY)
02941
RtlImageDirectoryEntryToData( ImageBase,
02942
TRUE,
02943 IMAGE_DIRECTORY_ENTRY_DEBUG,
02944 &DebugSize
02945 );
02946
if (!DebugDirectory) {
02947
return FALSE;
02948 }
02949
02950
02951
02952
02953
02954 } except (
EXCEPTION_EXECUTE_HANDLER) {
02955
return FALSE;
02956 }
02957
02958
return TRUE;
02959 }
02960
02961
02962 NTSYSAPI
02963
NTSTATUS
02964 NTAPI
02965 NtAreMappedFilesTheSame (
02966 IN PVOID File1MappedAsAnImage,
02967 IN PVOID File2MappedAsFile
02968 )
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001 {
03002
PMMVAD FoundVad1;
03003
PMMVAD FoundVad2;
03004
NTSTATUS Status;
03005
03006
LOCK_ADDRESS_SPACE (
PsGetCurrentProcess());
03007 FoundVad1 =
MiLocateAddress (File1MappedAsAnImage);
03008 FoundVad2 =
MiLocateAddress (File2MappedAsFile);
03009
03010
if ((FoundVad1 ==
NULL) ||
03011 (FoundVad2 ==
NULL)) {
03012
03013
03014
03015
03016
03017
03018
Status = STATUS_INVALID_ADDRESS;
03019
goto ErrorReturn;
03020 }
03021
03022
03023
03024
03025
03026
if ((FoundVad1->
u.VadFlags.PrivateMemory == 1) ||
03027 (FoundVad2->
u.VadFlags.PrivateMemory == 1)) {
03028
Status = STATUS_CONFLICTING_ADDRESSES;
03029
goto ErrorReturn;
03030 }
03031
03032
if ((FoundVad1->
ControlArea ==
NULL) ||
03033 (FoundVad2->
ControlArea ==
NULL)) {
03034
Status = STATUS_CONFLICTING_ADDRESSES;
03035
goto ErrorReturn;
03036 }
03037
03038
if ((FoundVad1->
ControlArea->
FilePointer ==
NULL) ||
03039 (FoundVad2->
ControlArea->
FilePointer ==
NULL)) {
03040
Status = STATUS_CONFLICTING_ADDRESSES;
03041
goto ErrorReturn;
03042 }
03043
03044
Status = STATUS_NOT_SAME_DEVICE;
03045
03046
if ((PVOID)FoundVad1->
ControlArea ==
03047 FoundVad2->
ControlArea->
FilePointer->
SectionObjectPointer->
ImageSectionObject) {
03048
Status = STATUS_SUCCESS;
03049 }
03050
03051 ErrorReturn:
03052
03053
UNLOCK_ADDRESS_SPACE (
PsGetCurrentProcess());
03054
return Status;
03055 }
03056
03057
03058
03059
VOID
03060 MiSetPageModified (
03061 IN PVOID Address
03062 )
03063
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089 {
03090
volatile PMMPTE PointerPpe;
03091
volatile PMMPTE PointerPde;
03092
volatile PMMPTE PointerPte;
03093
PMMPFN Pfn1;
03094
MMPTE PteContents;
03095 KIRQL OldIrql;
03096
03097
03098
03099
03100
03101
03102 PointerPte =
MiGetPteAddress (Address);
03103 PointerPde =
MiGetPdeAddress (Address);
03104 PointerPpe =
MiGetPpeAddress (Address);
03105
03106 *(
volatile CCHAR *)Address;
03107
03108
LOCK_PFN (OldIrql);
03109
03110
#if defined (_WIN64)
03111
while ((PointerPpe->
u.Hard.Valid == 0) ||
03112 (PointerPde->
u.Hard.Valid == 0) ||
03113 (PointerPte->
u.Hard.Valid == 0))
03114
#else
03115
while ((PointerPde->
u.Hard.Valid == 0) ||
03116 (PointerPte->
u.Hard.Valid == 0))
03117
#endif
03118
{
03119
03120
03121
03122
03123
03124
UNLOCK_PFN (OldIrql);
03125 *(
volatile CCHAR *)Address;
03126
LOCK_PFN (OldIrql);
03127 }
03128
03129 PteContents = *PointerPte;
03130
03131 Pfn1 =
MI_PFN_ELEMENT (PteContents.
u.Hard.PageFrameNumber);
03132 Pfn1->
u3.e1.Modified = 1;
03133
03134
if ((Pfn1->
OriginalPte.
u.Soft.Prototype == 0) &&
03135 (Pfn1->
u3.e1.WriteInProgress == 0)) {
03136
MiReleasePageFileSpace (Pfn1->
OriginalPte);
03137 Pfn1->
OriginalPte.
u.Soft.PageFileHigh = 0;
03138 }
03139
03140
#ifdef NT_UP
03141
if (
MI_IS_PTE_DIRTY (PteContents)) {
03142
#endif //NT_UP
03143
MI_SET_PTE_CLEAN (PteContents);
03144
03145
03146
03147
03148
03149 (
VOID)
KeFlushSingleTb (Address,
03150
FALSE,
03151
TRUE,
03152 (PHARDWARE_PTE)PointerPte,
03153 PteContents.
u.Flush);
03154
#ifdef NT_UP
03155
}
03156
#endif //NT_UP
03157
03158
UNLOCK_PFN (OldIrql);
03159
return;
03160 }
03161
03162
03163
NTSTATUS
03164 MmMapViewInSystemSpace (
03165 IN PVOID Section,
03166 OUT PVOID *MappedBase,
03167 IN OUT PSIZE_T ViewSize
03168 )
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196 {
03197
PMMSESSION Session;
03198
03199
PAGED_CODE();
03200
03201 Session = &
MmSession;
03202
03203
return MiMapViewInSystemSpace (Section,
03204 Session,
03205 MappedBase,
03206 ViewSize);
03207 }
03208
03209
03210
NTSTATUS
03211 MmMapViewInSessionSpace (
03212 IN PVOID Section,
03213 OUT PVOID *MappedBase,
03214 IN OUT PSIZE_T ViewSize
03215 )
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244 {
03245
PMMSESSION Session;
03246
03247
PAGED_CODE();
03248
03249
if (
MiHydra ==
TRUE) {
03250
if (
PsGetCurrentProcess()->Vm.u.Flags.ProcessInSession == 0) {
03251
return STATUS_NOT_MAPPED_VIEW;
03252 }
03253
ASSERT (
MmIsAddressValid(
MmSessionSpace) ==
TRUE);
03254 Session = &
MmSessionSpace->
Session;
03255 }
03256
else {
03257 Session = &
MmSession;
03258 }
03259
03260
return MiMapViewInSystemSpace (Section,
03261 Session,
03262 MappedBase,
03263 ViewSize);
03264 }
03265
03266
03267
NTSTATUS
03268 MiMapViewInSystemSpace (
03269 IN PVOID Section,
03270 IN
PMMSESSION Session,
03271 OUT PVOID *MappedBase,
03272 IN OUT PSIZE_T ViewSize
03273 )
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306 {
03307 PVOID Base;
03308 KIRQL OldIrql;
03309
PSUBSECTION Subsection;
03310
PCONTROL_AREA ControlArea;
03311
PCONTROL_AREA NewControlArea;
03312 ULONG StartBit;
03313 ULONG SizeIn64k;
03314 ULONG NewSizeIn64k;
03315
PMMPTE BasePte;
03316 ULONG NumberOfPtes;
03317 ULONG NumberOfBytes;
03318 BOOLEAN status;
03319 KIRQL WsIrql;
03320
03321
PAGED_CODE();
03322
03323
03324
03325
03326
03327
03328
03329 ControlArea = ((
PSECTION)Section)->
Segment->
ControlArea;
03330
03331
if (ControlArea->
u.Flags.GlobalOnlyPerSession == 0) {
03332 Subsection = (
PSUBSECTION)(ControlArea + 1);
03333 }
03334
else {
03335 Subsection = (
PSUBSECTION)((
PLARGE_CONTROL_AREA)ControlArea + 1);
03336 }
03337
03338
MmLockPagableSectionByHandle(
ExPageLockHandle);
03339
03340
if (
MiCheckPurgeAndUpMapCount (ControlArea) ==
FALSE) {
03341
MmUnlockPagableImageSection(
ExPageLockHandle);
03342
return STATUS_INSUFFICIENT_RESOURCES;
03343 }
03344
03345
if (*ViewSize == 0) {
03346
03347 *ViewSize = ((
PSECTION)Section)->SizeOfSection.LowPart;
03348
03349 }
else if (*ViewSize > ((
PSECTION)Section)->SizeOfSection.LowPart) {
03350
03351
03352
03353
03354
03355
LOCK_PFN (OldIrql);
03356 ControlArea->
NumberOfMappedViews -= 1;
03357 ControlArea->
NumberOfUserReferences -= 1;
03358
03359
03360
03361
03362
03363
03364
MiCheckControlArea (ControlArea,
NULL, OldIrql);
03365
03366
MmUnlockPagableImageSection(
ExPageLockHandle);
03367
return STATUS_INVALID_VIEW_SIZE;
03368 }
03369
03370
03371
03372
03373
03374 SizeIn64k = (ULONG)((*ViewSize /
X64K) + ((*ViewSize & (
X64K - 1)) != 0));
03375
03376 Base =
MiInsertInSystemSpace (Session, SizeIn64k, ControlArea);
03377
03378
if (Base ==
NULL) {
03379
LOCK_PFN (OldIrql);
03380 ControlArea->
NumberOfMappedViews -= 1;
03381 ControlArea->
NumberOfUserReferences -= 1;
03382
03383
03384
03385
03386
03387
03388
MiCheckControlArea (ControlArea,
NULL, OldIrql);
03389
03390
MmUnlockPagableImageSection(
ExPageLockHandle);
03391
return STATUS_NO_MEMORY;
03392 }
03393
03394 NumberOfBytes = SizeIn64k *
X64K;
03395
03396
if (Session == &
MmSession) {
03397 status =
MiFillSystemPageDirectory (Base, NumberOfBytes);
03398 }
03399
else {
03400
LOCK_SESSION_SPACE_WS (WsIrql);
03401
if (
NT_SUCCESS(
MiSessionCommitPageTables (Base,
03402 (PVOID)((ULONG_PTR)Base + NumberOfBytes - 1)))) {
03403 status =
TRUE;
03404 }
03405
else {
03406 status =
FALSE;
03407 }
03408 }
03409
03410
if (status ==
FALSE) {
03411
if (Session != &
MmSession) {
03412
UNLOCK_SESSION_SPACE_WS (WsIrql);
03413 }
03414
03415
LOCK_PFN (OldIrql);
03416 ControlArea->
NumberOfMappedViews -= 1;
03417 ControlArea->
NumberOfUserReferences -= 1;
03418
03419
03420
03421
03422
03423
03424
MiCheckControlArea (ControlArea,
NULL, OldIrql);
03425
03426 StartBit = (ULONG) (((ULONG_PTR)Base - (ULONG_PTR)Session->SystemSpaceViewStart) >> 16);
03427
03428
LOCK_SYSTEM_VIEW_SPACE (Session);
03429
03430 NewSizeIn64k =
MiRemoveFromSystemSpace (Session, Base, &NewControlArea);
03431
03432
ASSERT (ControlArea == NewControlArea);
03433
ASSERT (SizeIn64k == NewSizeIn64k);
03434
03435
RtlClearBits (Session->SystemSpaceBitMap, StartBit, SizeIn64k);
03436
03437
UNLOCK_SYSTEM_VIEW_SPACE (Session);
03438
03439
MmUnlockPagableImageSection(
ExPageLockHandle);
03440
return STATUS_NO_MEMORY;
03441 }
03442
03443
03444
03445
03446
03447
if (((
PSECTION)Section)->u.Flags.Image) {
03448
03449
#if DBG
03450
03451
03452
03453
03454
03455
03456
if (Session == &
MmSession) {
03457
ASSERT (((
PSECTION)Section)->Segment->ControlArea == ControlArea);
03458 }
03459
#endif
03460
03461
LOCK_PFN (OldIrql);
03462 ControlArea->
u.Flags.ImageMappedInSystemSpace = 1;
03463
UNLOCK_PFN (OldIrql);
03464 }
03465
03466 BasePte =
MiGetPteAddress (Base);
03467 NumberOfPtes =
BYTES_TO_PAGES (*ViewSize);
03468
03469
MiAddMappedPtes (BasePte,
03470 NumberOfPtes,
03471 ControlArea);
03472
03473
if (Session != &
MmSession) {
03474
UNLOCK_SESSION_SPACE_WS (WsIrql);
03475 }
03476
03477 *MappedBase = Base;
03478
03479
MmUnlockPagableImageSection(
ExPageLockHandle);
03480
return STATUS_SUCCESS;
03481 }
03482
03483 BOOLEAN
03484 MiFillSystemPageDirectory (
03485 PVOID Base,
03486 SIZE_T NumberOfBytes
03487 )
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512 {
03513
PMMPTE FirstPde;
03514
PMMPTE LastPde;
03515
PMMPTE FirstSystemPde;
03516
MMPTE TempPte;
03517 PFN_NUMBER PageFrameIndex;
03518 KIRQL OldIrql;
03519 ULONG i;
03520
03521
PAGED_CODE();
03522
03523
03524
03525
03526
03527 FirstPde =
MiGetPdeAddress (Base);
03528 LastPde =
MiGetPdeAddress ((PVOID)(((PCHAR)Base) + NumberOfBytes - 1));
03529
03530
#if defined (_WIN64)
03531
FirstSystemPde = FirstPde;
03532
#else
03533
#if !defined (_X86PAE_)
03534
FirstSystemPde = &
MmSystemPagePtes[((ULONG_PTR)FirstPde &
03535 ((
PDE_PER_PAGE *
sizeof(
MMPTE)) - 1)) /
sizeof(
MMPTE) ];
03536
#else
03537
FirstSystemPde = &
MmSystemPagePtes[((ULONG_PTR)FirstPde &
03538 (PD_PER_SYSTEM * (
PDE_PER_PAGE *
sizeof(
MMPTE)) - 1)) /
sizeof(
MMPTE) ];
03539
#endif
03540
#endif
03541
03542
do {
03543
if (FirstSystemPde->
u.Hard.Valid == 0) {
03544
03545
03546
03547
03548
03549 TempPte =
ValidKernelPde;
03550
03551
LOCK_PFN (OldIrql);
03552
03553
if (((
volatile MMPTE *)FirstSystemPde)->u.Hard.Valid == 0) {
03554
03555
if (
MiEnsureAvailablePageOrWait (
NULL, FirstPde)) {
03556
03557
03558
03559
03560
03561
03562
UNLOCK_PFN (OldIrql);
03563
continue;
03564 }
03565
03566
MiChargeCommitmentCantExpand (1,
TRUE);
03567
MM_TRACK_COMMIT (
MM_DBG_COMMIT_FILL_SYSTEM_DIRECTORY, 1);
03568 PageFrameIndex =
MiRemoveAnyPage (
03569
MI_GET_PAGE_COLOR_FROM_PTE (FirstSystemPde));
03570 TempPte.
u.Hard.PageFrameNumber = PageFrameIndex;
03571
MI_WRITE_VALID_PTE (FirstSystemPde, TempPte);
03572
MI_WRITE_VALID_PTE (FirstPde, TempPte);
03573
03574
#if defined (_WIN64)
03575
MiInitializePfn (PageFrameIndex,
03576 FirstPde,
03577 1);
03578
#else
03579
03580
#if !defined (_X86PAE_)
03581
MiInitializePfnForOtherProcess (PageFrameIndex,
03582 FirstPde,
03583
MmSystemPageDirectory);
03584
#else
03585
i = (FirstPde -
MiGetPdeAddress(0)) /
PDE_PER_PAGE;
03586
MiInitializePfnForOtherProcess (PageFrameIndex,
03587 FirstPde,
03588
MmSystemPageDirectory[i]);
03589
#endif
03590
03591
#endif
03592
03593
MiFillMemoryPte (
MiGetVirtualAddressMappedByPte (FirstPde),
03594
PAGE_SIZE,
03595
MM_ZERO_KERNEL_PTE);
03596 }
03597
UNLOCK_PFN (OldIrql);
03598 }
03599
03600 FirstSystemPde += 1;
03601 FirstPde += 1;
03602 }
while (FirstPde <= LastPde );
03603
03604
return TRUE;
03605 }
03606
03607
NTSTATUS
03608 MmUnmapViewInSystemSpace (
03609 IN PVOID MappedBase
03610 )
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632 {
03633
PAGED_CODE();
03634
03635
return MiUnmapViewInSystemSpace (&
MmSession, MappedBase);
03636 }
03637
03638
NTSTATUS
03639 MmUnmapViewInSessionSpace (
03640 IN PVOID MappedBase
03641 )
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663 {
03664
PMMSESSION Session;
03665
03666
PAGED_CODE();
03667
03668
if (
MiHydra ==
TRUE) {
03669
if (
PsGetCurrentProcess()->Vm.u.Flags.ProcessInSession == 0) {
03670
return STATUS_NOT_MAPPED_VIEW;
03671 }
03672
ASSERT (
MmIsAddressValid(
MmSessionSpace) ==
TRUE);
03673 Session = &
MmSessionSpace->
Session;
03674 }
03675
else {
03676 Session = &
MmSession;
03677 }
03678
03679
return MiUnmapViewInSystemSpace (Session, MappedBase);
03680 }
03681
03682
NTSTATUS
03683 MiUnmapViewInSystemSpace (
03684 IN
PMMSESSION Session,
03685 IN PVOID MappedBase
03686 )
03687
03688
03689
03690
03691
03692
03693
03694
03695
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707
03708
03709
03710 {
03711 ULONG StartBit;
03712 ULONG
Size;
03713
PCONTROL_AREA ControlArea;
03714
PMMSUPPORT Ws;
03715 KIRQL WsIrql;
03716
03717
PAGED_CODE();
03718
03719
MmLockPagableSectionByHandle(
ExPageLockHandle);
03720 StartBit = (ULONG) (((ULONG_PTR)MappedBase - (ULONG_PTR)Session->SystemSpaceViewStart) >> 16);
03721
03722
LOCK_SYSTEM_VIEW_SPACE (Session);
03723
03724
Size =
MiRemoveFromSystemSpace (Session, MappedBase, &ControlArea);
03725
03726
RtlClearBits (Session->SystemSpaceBitMap, StartBit,
Size);
03727
03728
03729
03730
03731
03732
Size =
Size * (
X64K >>
PAGE_SHIFT);
03733
03734
if (Session == &
MmSession) {
03735 Ws = &
MmSystemCacheWs;
03736 }
03737
else {
03738 Ws = &
MmSessionSpace->
Vm;
03739
LOCK_SESSION_SPACE_WS(WsIrql);
03740 }
03741
03742
MiRemoveMappedPtes (MappedBase,
Size, ControlArea, Ws);
03743
03744
if (Session != &
MmSession) {
03745
UNLOCK_SESSION_SPACE_WS(WsIrql);
03746 }
03747
03748
UNLOCK_SYSTEM_VIEW_SPACE (Session);
03749
03750
MmUnlockPagableImageSection(
ExPageLockHandle);
03751
03752
return STATUS_SUCCESS;
03753 }
03754
03755
03756 PVOID
03757 MiInsertInSystemSpace (
03758 IN
PMMSESSION Session,
03759 IN ULONG SizeIn64k,
03760 IN
PCONTROL_AREA ControlArea
03761 )
03762
03763
03764
03765
03766
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784
03785
03786
03787 {
03788
03789 PVOID Base;
03790 ULONG_PTR Entry;
03791 ULONG Hash;
03792 ULONG i;
03793 ULONG AllocSize;
03794
PMMVIEW OldTable;
03795 ULONG StartBit;
03796 ULONG NewHashSize;
03797
03798
PAGED_CODE();
03799
03800
03801
03802
03803
03804
LOCK_SYSTEM_VIEW_SPACE (Session);
03805
03806
if (Session->SystemSpaceHashEntries + 8 > Session->SystemSpaceHashSize) {
03807
03808
03809
03810
03811
03812 NewHashSize = Session->SystemSpaceHashSize << 1;
03813
03814 AllocSize =
sizeof(
MMVIEW) * NewHashSize;
03815
ASSERT (AllocSize <
PAGE_SIZE);
03816
03817 OldTable = Session->SystemSpaceViewTable;
03818
03819 Session->SystemSpaceViewTable =
ExAllocatePoolWithTag (
PagedPool,
03820 AllocSize,
03821 ' mM');
03822
03823
if (Session->SystemSpaceViewTable ==
NULL) {
03824 Session->SystemSpaceViewTable = OldTable;
03825 }
03826
else {
03827 RtlZeroMemory (Session->SystemSpaceViewTable, AllocSize);
03828
03829 Session->SystemSpaceHashSize = NewHashSize;
03830 Session->SystemSpaceHashKey = Session->SystemSpaceHashSize - 1;
03831
03832
for (i = 0; i < (Session->SystemSpaceHashSize / 2); i += 1) {
03833
if (OldTable[i].
Entry != 0) {
03834 Hash = (ULONG) ((OldTable[i].
Entry >> 16) % Session->SystemSpaceHashKey);
03835
03836
while (Session->SystemSpaceViewTable[Hash].Entry != 0) {
03837 Hash += 1;
03838
if (Hash >= Session->SystemSpaceHashSize) {
03839 Hash = 0;
03840 }
03841 }
03842 Session->SystemSpaceViewTable[Hash] = OldTable[i];
03843 }
03844 }
03845
ExFreePool (OldTable);
03846 }
03847 }
03848
03849
if (Session->SystemSpaceHashEntries == Session->SystemSpaceHashSize) {
03850
03851
03852
03853
03854
03855
03856
UNLOCK_SYSTEM_VIEW_SPACE (Session);
03857
return NULL;
03858 }
03859
03860 StartBit =
RtlFindClearBitsAndSet (Session->SystemSpaceBitMap,
03861 SizeIn64k,
03862 0);
03863
03864
if (StartBit == 0xFFFFFFFF) {
03865
UNLOCK_SYSTEM_VIEW_SPACE (Session);
03866
return NULL;
03867 }
03868
03869 Base = (PVOID)((PCHAR)Session->SystemSpaceViewStart + (StartBit *
X64K));
03870
03871 Entry = (ULONG_PTR)
MI_64K_ALIGN(Base) + SizeIn64k;
03872
03873 Hash = (ULONG) ((Entry >> 16) % Session->SystemSpaceHashKey);
03874
03875
while (Session->SystemSpaceViewTable[Hash].Entry != 0) {
03876 Hash += 1;
03877
if (Hash >= Session->SystemSpaceHashSize) {
03878 Hash = 0;
03879 }
03880 }
03881
03882 Session->SystemSpaceHashEntries += 1;
03883
03884 Session->SystemSpaceViewTable[Hash].Entry = Entry;
03885 Session->SystemSpaceViewTable[Hash].ControlArea = ControlArea;
03886
03887
UNLOCK_SYSTEM_VIEW_SPACE (Session);
03888
return Base;
03889 }
03890
03891
03892 ULONG
03893 MiRemoveFromSystemSpace (
03894 IN
PMMSESSION Session,
03895 IN PVOID Base,
03896 OUT
PCONTROL_AREA *ControlArea
03897 )
03898
03899
03900
03901
03902
03903
03904
03905
03906
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924
03925
03926 {
03927 ULONG_PTR Base16;
03928 ULONG Hash;
03929 ULONG
Size;
03930 ULONG count;
03931
03932
PAGED_CODE();
03933
03934 count = 0;
03935
03936
03937
03938
03939
03940 Base16 = (ULONG_PTR)Base >> 16;
03941 Hash = (ULONG)(Base16 % Session->SystemSpaceHashKey);
03942
03943
while ((Session->SystemSpaceViewTable[Hash].Entry >> 16) != Base16) {
03944 Hash += 1;
03945
if (Hash >= Session->SystemSpaceHashSize) {
03946 Hash = 0;
03947 count += 1;
03948
if (count == 2) {
03949
KeBugCheckEx (DRIVER_UNMAPPING_INVALID_VIEW,
03950 (ULONG_PTR)Base,
03951
MiHydra,
03952 0,
03953 0);
03954 }
03955 }
03956 }
03957
03958 Session->SystemSpaceHashEntries -= 1;
03959
Size = (ULONG) (Session->SystemSpaceViewTable[Hash].Entry & 0xFFFF);
03960 Session->SystemSpaceViewTable[Hash].Entry = 0;
03961 *ControlArea = Session->SystemSpaceViewTable[Hash].ControlArea;
03962
return Size;
03963 }
03964
03965
03966 BOOLEAN
03967 MiInitializeSystemSpaceMap (
03968 PVOID InputSession OPTIONAL
03969 )
03970
03971
03972
03973
03974
03975
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985
03986
03987
03988
03989
03990
03991
03992
03993
03994 {
03995 ULONG AllocSize;
03996 ULONG
Size;
03997 PCHAR ViewStart;
03998
PMMSESSION Session;
03999
04000
if (ARGUMENT_PRESENT (InputSession)) {
04001 Session = (
PMMSESSION)InputSession;
04002 ViewStart = (PCHAR)
MI_SESSION_VIEW_START;
04003
Size =
MI_SESSION_VIEW_SIZE;
04004 }
04005
else {
04006 Session = &
MmSession;
04007 ViewStart = (PCHAR)
MiSystemViewStart;
04008
if (
MiHydra ==
TRUE) {
04009
Size =
MM_SYSTEM_VIEW_SIZE_IF_HYDRA;
04010 }
04011
else {
04012
Size =
MM_SYSTEM_VIEW_SIZE;
04013 }
04014 }
04015
04016
04017
04018
04019
04020
04021
04022
04023
04024 Session->
SystemSpaceViewLockPointer = &Session->
SystemSpaceViewLock;
04025
ExInitializeFastMutex(Session->
SystemSpaceViewLockPointer);
04026
04027
04028
04029
04030
04031
04032
04033 Session->
SystemSpaceViewStart = ViewStart;
04034
04035
MiCreateBitMap (&Session->
SystemSpaceBitMap,
Size /
X64K,
NonPagedPool);
04036
if (Session->
SystemSpaceBitMap ==
NULL) {
04037
MM_BUMP_SESSION_FAILURES (
MM_SESSION_FAILURE_NO_NONPAGED_POOL);
04038
return FALSE;
04039 }
04040
04041
RtlClearAllBits (Session->
SystemSpaceBitMap);
04042
04043
04044
04045
04046
04047 Session->
SystemSpaceHashSize = 31;
04048 Session->
SystemSpaceHashKey = Session->
SystemSpaceHashSize - 1;
04049 Session->
SystemSpaceHashEntries = 0;
04050
04051 AllocSize =
sizeof(
MMVIEW) * Session->
SystemSpaceHashSize;
04052
ASSERT (AllocSize <
PAGE_SIZE);
04053
04054 Session->
SystemSpaceViewTable =
ExAllocatePoolWithTag (
PagedPool,
04055 AllocSize,
04056 ' mM');
04057
04058
if (Session->
SystemSpaceViewTable ==
NULL) {
04059
MM_BUMP_SESSION_FAILURES (
MM_SESSION_FAILURE_NO_SESSION_PAGED_POOL);
04060
MiRemoveBitMap (&Session->
SystemSpaceBitMap);
04061
return FALSE;
04062 }
04063
04064 RtlZeroMemory (Session->
SystemSpaceViewTable, AllocSize);
04065
04066
return TRUE;
04067 }
04068
04069
04070
VOID
04071 MiFreeSessionSpaceMap (
04072 VOID
04073 )
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083
04084
04085
04086
04087
04088
04089
04090
04091
04092
04093
04094
04095 {
04096
PMMSESSION Session;
04097
04098
PAGED_CODE();
04099
04100 Session = &
MmSessionSpace->
Session;
04101
04102
04103
04104
04105
04106
LOCK_SYSTEM_VIEW_SPACE (Session);
04107
04108
if (Session->
SystemSpaceViewTable && Session->
SystemSpaceHashEntries) {
04109
04110
KeBugCheckEx (SESSION_HAS_VALID_VIEWS_ON_EXIT,
04111 (ULONG_PTR)
MmSessionSpace->
SessionId,
04112 Session->
SystemSpaceHashEntries,
04113 (ULONG_PTR)&Session->
SystemSpaceViewTable[0],
04114 Session->
SystemSpaceHashSize);
04115
04116
#if 0
04117
ULONG
Index;
04118
04119
for (
Index = 0;
Index < Session->
SystemSpaceHashSize;
Index += 1) {
04120
04121
PMMVIEW Table;
04122 PVOID Base;
04123
04124 Table = &Session->
SystemSpaceViewTable[
Index];
04125
04126
if (Table->
Entry) {
04127
04128
#if DBG
04129
DbgPrint (
"MM: MiFreeSessionSpaceMap: view entry %d leak: ControlArea %p, Addr %p, Size %d\n",
04130
Index,
04131 Table->
ControlArea,
04132 Table->
Entry & ~0xFFFF,
04133 Table->
Entry & 0x0000FFFF
04134 );
04135
#endif
04136
04137 Base = (PVOID)(Table->
Entry & ~0xFFFF);
04138
04139
04140
04141
04142
04143
UNLOCK_SYSTEM_VIEW_SPACE(Session);
04144
04145
MiUnmapViewInSystemSpace (Session, Base);
04146
04147
LOCK_SYSTEM_VIEW_SPACE (Session);
04148
04149
04150
04151
04152
04153
04154
if (Session->
SystemSpaceViewTable ==
NULL) {
04155
break;
04156 }
04157 }
04158 }
04159
#endif
04160
04161 }
04162
04163
UNLOCK_SYSTEM_VIEW_SPACE (Session);
04164
04165
if (Session->
SystemSpaceViewTable) {
04166
ExFreePool (Session->
SystemSpaceViewTable);
04167 Session->
SystemSpaceViewTable =
NULL;
04168 }
04169
04170
if (Session->
SystemSpaceBitMap) {
04171
MiRemoveBitMap (&Session->
SystemSpaceBitMap);
04172 }
04173 }
04174
04175
04176 HANDLE
04177 MmSecureVirtualMemory (
04178 IN PVOID Address,
04179 IN SIZE_T Size,
04180 IN ULONG ProbeMode
04181 )
04182
04183
04184
04185
04186
04187
04188
04189
04190
04191
04192
04193
04194
04195
04196
04197
04198
04199
04200
04201
04202
04203
04204
04205
04206
04207
04208
04209
04210
04211
04212
04213
04214
04215 {
04216 ULONG_PTR EndAddress;
04217 PVOID StartAddress;
04218
CHAR Temp;
04219 ULONG Probe;
04220 HANDLE
Handle;
04221
PMMVAD Vad;
04222
PMMVAD NewVad;
04223
PMMSECURE_ENTRY Secure;
04224
PEPROCESS Process;
04225
PMMPTE PointerPpe;
04226
PMMPTE PointerPde;
04227
PMMPTE PointerPte;
04228
PMMPTE LastPte;
04229
MMLOCK_CONFLICT Conflict;
04230 ULONG Waited;
04231
04232
PAGED_CODE();
04233
04234
if ((ULONG_PTR)Address +
Size > (ULONG_PTR)MM_HIGHEST_USER_ADDRESS || (ULONG_PTR)Address +
Size <= (ULONG_PTR)Address) {
04235
return (HANDLE)0;
04236 }
04237
04238
Handle = (HANDLE)0;
04239
04240 Probe = (ProbeMode == PAGE_READONLY);
04241
04242 Process =
PsGetCurrentProcess();
04243 StartAddress = Address;
04244
04245
LOCK_ADDRESS_SPACE (Process);
04246
04247
04248
04249
04250
04251
04252
04253
if (
Size >= 64 * 1024) {
04254 EndAddress = (ULONG_PTR)StartAddress +
Size - 1;
04255 Vad =
MiLocateAddress (StartAddress);
04256
04257
if (Vad ==
NULL) {
04258
goto Return1;
04259 }
04260
04261
if (Vad->
u.VadFlags.UserPhysicalPages == 1) {
04262
goto Return1;
04263 }
04264
04265
if (Vad->
u.VadFlags.MemCommit == 0) {
04266
goto LongWay;
04267 }
04268
04269
if (Vad->
u.VadFlags.PrivateMemory == 0) {
04270
goto LongWay;
04271 }
04272
04273
if (Vad->
u.VadFlags.PhysicalMapping == 1) {
04274
goto LongWay;
04275 }
04276
04277
ASSERT (Vad->
u.VadFlags.Protection);
04278
04279
if ((
MI_VA_TO_VPN (StartAddress) < Vad->
StartingVpn) ||
04280 (
MI_VA_TO_VPN (EndAddress) > Vad->
EndingVpn)) {
04281
goto Return1;
04282 }
04283
04284
if (Vad->
u.VadFlags.Protection ==
MM_NOACCESS) {
04285
goto LongWay;
04286 }
04287
04288
if (ProbeMode == PAGE_READONLY) {
04289
if (Vad->
u.VadFlags.Protection >
MM_EXECUTE_WRITECOPY) {
04290
goto LongWay;
04291 }
04292 }
04293
else {
04294
if (Vad->
u.VadFlags.Protection !=
MM_READWRITE &&
04295 Vad->
u.VadFlags.Protection !=
MM_EXECUTE_READWRITE) {
04296
goto LongWay;
04297 }
04298 }
04299
04300
04301
04302
04303
04304 PointerPde =
MiGetPdeAddress (StartAddress);
04305 PointerPpe =
MiGetPteAddress (PointerPde);
04306 PointerPte =
MiGetPteAddress (StartAddress);
04307 LastPte =
MiGetPteAddress (EndAddress);
04308
04309
LOCK_WS_UNSAFE (Process);
04310
04311
do {
04312
04313
while (
MiDoesPpeExistAndMakeValid (PointerPpe,
04314 Process,
04315
FALSE,
04316 &Waited) ==
FALSE) {
04317
04318
04319
04320
04321 PointerPpe += 1;
04322 PointerPde =
MiGetVirtualAddressMappedByPte (PointerPpe);
04323 PointerPte =
MiGetVirtualAddressMappedByPte (PointerPde);
04324
if (PointerPte > LastPte) {
04325
UNLOCK_WS_UNSAFE (Process);
04326
goto EditVad;
04327 }
04328 }
04329
04330 Waited = 0;
04331
04332
while (
MiDoesPdeExistAndMakeValid (PointerPde,
04333 Process,
04334
FALSE,
04335 &Waited) ==
FALSE) {
04336
04337
04338
04339
04340 PointerPde += 1;
04341 PointerPpe =
MiGetPteAddress (PointerPde);
04342 PointerPte =
MiGetVirtualAddressMappedByPte (PointerPde);
04343
if (PointerPte > LastPte) {
04344
UNLOCK_WS_UNSAFE (Process);
04345
goto EditVad;
04346 }
04347
#if defined (_WIN64)
04348
if (
MiIsPteOnPdeBoundary (PointerPde)) {
04349 Waited = 1;
04350
break;
04351 }
04352
#endif
04353
}
04354
04355 }
while (Waited != 0);
04356
04357
while (PointerPte <= LastPte) {
04358
04359
if (
MiIsPteOnPdeBoundary (PointerPte)) {
04360
04361 PointerPde =
MiGetPteAddress (PointerPte);
04362 PointerPpe =
MiGetPteAddress (PointerPde);
04363
04364
do {
04365
04366
while (
MiDoesPpeExistAndMakeValid (PointerPpe,
04367 Process,
04368
FALSE,
04369 &Waited) ==
FALSE) {
04370
04371
04372
04373
04374 PointerPpe += 1;
04375 PointerPde =
MiGetVirtualAddressMappedByPte (PointerPpe);
04376 PointerPte =
MiGetVirtualAddressMappedByPte (PointerPde);
04377
04378
if (PointerPte > LastPte) {
04379
UNLOCK_WS_UNSAFE (Process);
04380
goto EditVad;
04381 }
04382 }
04383
04384 Waited = 0;
04385
04386
while (
MiDoesPdeExistAndMakeValid (PointerPde,
04387 Process,
04388
FALSE,
04389 &Waited) ==
FALSE) {
04390
04391
04392
04393
04394 PointerPde += 1;
04395 PointerPpe =
MiGetPteAddress (PointerPde);
04396 PointerPte =
MiGetVirtualAddressMappedByPte (PointerPde);
04397
if (PointerPte > LastPte) {
04398
UNLOCK_WS_UNSAFE (Process);
04399
goto EditVad;
04400 }
04401
#if defined (_WIN64)
04402
if (
MiIsPteOnPdeBoundary (PointerPde)) {
04403 Waited = 1;
04404
break;
04405 }
04406
#endif
04407
}
04408
04409 }
while (Waited != 0);
04410 }
04411
if (PointerPte->
u.Long) {
04412
UNLOCK_WS_UNSAFE (Process);
04413
goto LongWay;
04414 }
04415 PointerPte += 1;
04416 }
04417
UNLOCK_WS_UNSAFE (Process);
04418 }
04419
else {
04420 LongWay:
04421
04422
MiInsertConflictInList (&Conflict);
04423
04424
try {
04425
04426
if (ProbeMode == PAGE_READONLY) {
04427
04428 EndAddress = (ULONG_PTR)Address +
Size - 1;
04429 EndAddress = (EndAddress & ~(
PAGE_SIZE - 1)) +
PAGE_SIZE;
04430
04431
do {
04432 Temp = *(
volatile CHAR *)Address;
04433 Address = (PVOID)(((ULONG_PTR)Address & ~(
PAGE_SIZE - 1)) +
PAGE_SIZE);
04434 }
while ((ULONG_PTR)Address != EndAddress);
04435 }
else {
04436
ProbeForWrite (Address, (ULONG)
Size, 1);
04437 }
04438
04439 } except (
EXCEPTION_EXECUTE_HANDLER) {
04440
MiRemoveConflictFromList (&Conflict);
04441
goto Return1;
04442 }
04443
04444
MiRemoveConflictFromList (&Conflict);
04445
04446
04447
04448
04449
04450 EndAddress = (ULONG_PTR)StartAddress +
Size - 1;
04451 Vad =
MiLocateAddress (StartAddress);
04452
04453
if (Vad ==
NULL) {
04454
goto Return1;
04455 }
04456
04457
if (Vad->
u.VadFlags.UserPhysicalPages == 1) {
04458
goto Return1;
04459 }
04460
04461
if ((
MI_VA_TO_VPN (StartAddress) < Vad->
StartingVpn) ||
04462 (
MI_VA_TO_VPN (EndAddress) > Vad->
EndingVpn)) {
04463
04464
04465
04466
04467
04468
04469
goto Return1;
04470 }
04471 }
04472
04473 EditVad:
04474
04475
04476
04477
04478
04479
04480
if ((Vad->
u.VadFlags.PrivateMemory) && (!Vad->
u.VadFlags.NoChange)) {
04481
04482 NewVad =
ExAllocatePoolWithTag (
NonPagedPool,
04483
sizeof(
MMVAD),
04484
MMVADKEY);
04485
if (NewVad ==
NULL) {
04486
goto Return1;
04487 }
04488
04489 RtlZeroMemory (NewVad,
sizeof(
MMVAD));
04490 RtlCopyMemory (NewVad, Vad,
sizeof(
MMVAD_SHORT));
04491 NewVad->
u.VadFlags.NoChange = 1;
04492 NewVad->
u2.VadFlags2.OneSecured = 1;
04493 NewVad->
u2.VadFlags2.StoredInVad = 1;
04494 NewVad->
u2.VadFlags2.ReadOnly = Probe;
04495 NewVad->
u3.Secured.StartVpn = (ULONG_PTR)StartAddress;
04496 NewVad->
u3.Secured.EndVpn = EndAddress;
04497
04498
04499
04500
04501
04502
LOCK_WS_UNSAFE (Process);
04503
if (Vad->
Parent) {
04504
if (Vad->
Parent->
RightChild == Vad) {
04505 Vad->
Parent->
RightChild = NewVad;
04506 }
else {
04507
ASSERT (Vad->
Parent->
LeftChild == Vad);
04508 Vad->
Parent->
LeftChild = NewVad;
04509 }
04510 }
else {
04511 Process->
VadRoot = NewVad;
04512 }
04513
if (Vad->
LeftChild) {
04514 Vad->
LeftChild->
Parent = NewVad;
04515 }
04516
if (Vad->
RightChild) {
04517 Vad->
RightChild->
Parent = NewVad;
04518 }
04519
if (Process->
VadHint == Vad) {
04520 Process->
VadHint = NewVad;
04521 }
04522
if (Process->
VadFreeHint == Vad) {
04523 Process->
VadFreeHint = NewVad;
04524 }
04525
04526
if ((Vad->
u.VadFlags.PhysicalMapping == 1) ||
04527 (Vad->
u.VadFlags.WriteWatch == 1)) {
04528
04529
MiPhysicalViewAdjuster (Process, Vad, NewVad);
04530 }
04531
04532
UNLOCK_WS_UNSAFE (Process);
04533
ExFreePool (Vad);
04534
Handle = (HANDLE)&NewVad->
u2.LongFlags2;
04535
goto Return1;
04536 }
04537
04538
04539
04540
04541
04542
if (Vad->
u2.VadFlags2.OneSecured) {
04543
04544
04545
04546
04547
04548
04549 Secure =
ExAllocatePoolWithTag (
NonPagedPool,
04550
sizeof (
MMSECURE_ENTRY),
04551 'eSmM');
04552
if (Secure ==
NULL) {
04553
goto Return1;
04554 }
04555
04556
ASSERT (Vad->
u.VadFlags.NoChange == 1);
04557 Vad->
u2.VadFlags2.OneSecured = 0;
04558 Vad->
u2.VadFlags2.MultipleSecured = 1;
04559 Secure->
u2.LongFlags2 = (ULONG) Vad->
u.LongFlags;
04560 Secure->
u2.VadFlags2.StoredInVad = 0;
04561 Secure->
StartVpn = Vad->
u3.Secured.StartVpn;
04562 Secure->
EndVpn = Vad->
u3.Secured.EndVpn;
04563
04564 InitializeListHead (&Vad->
u3.List);
04565 InsertTailList (&Vad->
u3.List,
04566 &Secure->
List);
04567 }
04568
04569
if (Vad->
u2.VadFlags2.MultipleSecured) {
04570
04571
04572
04573
04574
04575
04576 Secure =
ExAllocatePoolWithTag (
NonPagedPool,
04577
sizeof (
MMSECURE_ENTRY),
04578 'eSmM');
04579
if (Secure ==
NULL) {
04580
goto Return1;
04581 }
04582
04583 Secure->
u2.LongFlags2 = 0;
04584 Secure->
u2.VadFlags2.ReadOnly = Probe;
04585 Secure->
StartVpn = (ULONG_PTR)StartAddress;
04586 Secure->
EndVpn = EndAddress;
04587
04588 InsertTailList (&Vad->
u3.List,
04589 &Secure->
List);
04590
Handle = (HANDLE)Secure;
04591
04592 }
else {
04593
04594
04595
04596
04597
04598 Vad->
u.VadFlags.NoChange = 1;
04599 Vad->
u2.VadFlags2.OneSecured = 1;
04600 Vad->
u2.VadFlags2.StoredInVad = 1;
04601 Vad->
u2.VadFlags2.ReadOnly = Probe;
04602 Vad->
u3.Secured.StartVpn = (ULONG_PTR)StartAddress;
04603 Vad->
u3.Secured.EndVpn = EndAddress;
04604
Handle = (HANDLE)&Vad->
u2.LongFlags2;
04605 }
04606
04607 Return1:
04608
UNLOCK_ADDRESS_SPACE (Process);
04609
return Handle;
04610 }
04611
04612
04613
VOID
04614 MmUnsecureVirtualMemory (
04615 IN HANDLE SecureHandle
04616 )
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636
04637
04638
04639 {
04640
PMMSECURE_ENTRY Secure;
04641
PEPROCESS Process;
04642
PMMVAD Vad;
04643
04644
PAGED_CODE();
04645
04646 Secure = (
PMMSECURE_ENTRY)SecureHandle;
04647 Process =
PsGetCurrentProcess ();
04648
LOCK_ADDRESS_SPACE (Process);
04649
04650
if (Secure->
u2.VadFlags2.StoredInVad) {
04651 Vad = CONTAINING_RECORD( Secure,
04652
MMVAD,
04653 u2.
LongFlags2);
04654 }
else {
04655 Vad =
MiLocateAddress ((PVOID)Secure->
StartVpn);
04656 }
04657
04658
ASSERT (Vad);
04659
ASSERT (Vad->
u.VadFlags.NoChange == 1);
04660
04661
if (Vad->
u2.VadFlags2.OneSecured) {
04662
ASSERT (Secure == (
PMMSECURE_ENTRY)&Vad->
u2.LongFlags2);
04663 Vad->
u2.VadFlags2.OneSecured = 0;
04664
ASSERT (Vad->
u2.VadFlags2.MultipleSecured == 0);
04665
if (Vad->
u2.VadFlags2.SecNoChange == 0) {
04666
04667
04668
04669
04670
04671 Vad->
u.VadFlags.NoChange = 0;
04672 }
04673 }
else {
04674
ASSERT (Vad->
u2.VadFlags2.MultipleSecured == 1);
04675
04676
if (Secure == (
PMMSECURE_ENTRY)&Vad->
u2.LongFlags2) {
04677
04678
04679
04680
04681
04682
04683 Secure = CONTAINING_RECORD (Vad->
u3.List.Flink,
04684
MMSECURE_ENTRY,
04685
List);
04686 }
04687 RemoveEntryList (&Secure->
List);
04688
ExFreePool (Secure);
04689
if (IsListEmpty (&Vad->
u3.List)) {
04690
04691
04692
04693
04694
04695 Vad->
u2.VadFlags2.MultipleSecured = 0;
04696
04697
if ((Vad->
u2.VadFlags2.SecNoChange == 0) &&
04698 (Vad->
u.VadFlags.PrivateMemory == 0)) {
04699
04700
04701
04702
04703
04704
04705
04706
04707 Vad->
u.VadFlags.NoChange = 0;
04708 }
04709 }
04710 }
04711
04712
UNLOCK_ADDRESS_SPACE (Process);
04713
return;
04714 }