00086 :
00087
00088 This function creates a region of pages within
the virtual address
00089 space of a subject process.
00090
00091 Arguments:
00092
00093 ProcessHandle - Supplies an open handle to a process object.
00094
00095 BaseAddress - Supplies a pointer to a variable that will receive
00096
the base address of
the allocated region of pages.
00097 If
the initial value of
this argument
is not null,
00098 then
the region will be allocated starting at
the
00099 specified
virtual address rounded down to
the next
00100 host page size address boundary. If
the initial
00101 value of
this argument
is null, then
the operating
00102 system will determine where to allocate
the region.
00103
00104 ZeroBits - Supplies
the number of
high order address bits that
00105 must be zero in
the base address of
the section view. The
00106 value of
this argument must be less than or equal to
the
00107 maximum number of zero bits and
is only used when memory
00108 management determines where to allocate
the view (i.e. when
00109 BaseAddress is null).
00110
00111 If ZeroBits
is zero, then no zero bit constraints are applied.
00112
00113 If ZeroBits
is greater than 0 and less than 32, then
it is
00114
the number of leading zero bits from bit 31. Bits 63:32 are
00115 also required to be zero. This retains compatibility
00116 with 32-bit systems.
00117
00118 If ZeroBits
is greater than 32, then
it is considered as
00119 a mask and then number of leading zero are counted
out
00120 in
the mask. This then becomes
the zero bits argument.
00121
00122 RegionSize - Supplies a pointer to a variable that will receive
00123
the actual size in bytes of
the allocated region
00124 of pages. The initial value of
this argument
00125 specifies
the size in bytes of
the region and
is
00126 rounded up to
the next host page size boundary.
00127
00128 AllocationType - Supplies a set of flags that describe
the type
00129 of allocation that
is to be performed
for the
00130 specified region of pages. Flags are:
00131
00132
00133 MEM_COMMIT - The specified region of pages
is to
00134 be committed.
00135
00136 MEM_RESERVE - The specified region of pages
is to
00137 be reserved.
00138
00139 MEM_TOP_DOWN - The specified region should be created at
the
00140 highest
virtual address possible based on ZeroBits.
00141
00142 MEM_RESET - Reset
the state of
the specified region so
00143 that
if the pages are in page paging
file, they
00144 are discarded and pages of zeroes are brought in.
00145 If
the pages are in memory and modified, they are marked
00146 as not modified so they will not be written
out to
00147
the paging
file. The contents are NOT zeroed.
00148
00149 The Protect argument
is ignored, but a valid protection
00150 must be specified.
00151
00152 Protect - Supplies
the protection desired
for the committed
00153 region of pages.
00154
00155 Protect Values:
00156
00157
00158 PAGE_NOACCESS - No access to
the committed region
00159 of pages
is allowed. An attempt to read,
00160 write, or execute
the committed region
00161 results in an access violation (i.e. a GP
00162 fault).
00163
00164 PAGE_EXECUTE - Execute access to
the committed
00165 region of pages
is allowed. An attempt to
00166 read or write
the committed region results in
00167 an access violation.
00168
00169 PAGE_READONLY - Read
only and execute access to
the
00170 committed region of pages
is allowed. An
00171 attempt to write
the committed region results
00172 in an access violation.
00173
00174 PAGE_READWRITE - Read, write, and execute access to
00175
the committed region of pages
is allowed. If
00176 write access to
the underlying section
is
00177 allowed, then a single copy of
the pages are
00178 shared. Otherwise
the pages are shared read
00179
only/copy on write.
00180
00181 PAGE_NOCACHE - The region of pages should be allocated
00182 as non-cachable.
00183
00184 Return Value:
00185
00186 Various
NTSTATUS codes.
00187
00188 --*/
00189
00190 {
00191
PMMVAD Vad;
00192
PMMVAD FoundVad;
00193
PEPROCESS Process;
00194
KPROCESSOR_MODE PreviousMode;
00195 PVOID StartingAddress;
00196 PVOID EndingAddress;
00197
NTSTATUS Status;
00198 PVOID TopAddress;
00199 PVOID CapturedBase;
00200 SIZE_T CapturedRegionSize;
00201
PMMPTE PointerPte;
00202
PMMPTE CommitLimitPte;
00203 ULONG ProtectionMask;
00204
PMMPTE LastPte;
00205
PMMPTE PointerPde;
00206
PMMPTE PointerPpe;
00207
PMMPTE StartingPte;
00208
MMPTE TempPte;
00209 ULONG OldProtect;
00210 SSIZE_T QuotaCharge;
00211 SIZE_T QuotaFree;
00212 SIZE_T CopyOnWriteCharge;
00213 BOOLEAN PageFileChargeSucceeded;
00214 BOOLEAN Attached;
00215 LOGICAL ChargedExactQuota;
00216
MMPTE DecommittedPte;
00217 ULONG ChangeProtection;
00218 PVOID UsedPageDirectoryHandle;
00219 PVOID UsedPageTableHandle;
00220 PUCHAR Va;
00221 LOGICAL ChargedJobCommit;
00222
PMI_PHYSICAL_VIEW PhysicalView;
00223 PRTL_BITMAP
BitMap;
00224 ULONG BitMapSize;
00225 ULONG BitMapBits;
00226
#if defined(_MIALT4K_)
00227
PVOID OriginalBase;
00228 SIZE_T OriginalRegionSize;
00229 BOOLEAN EmulationFor4kPage =
FALSE;
00230 PVOID StartingAddressFor4k;
00231 PVOID EndingAddressFor4k;
00232 SIZE_T CapturedRegionSizeFor4k;
00233 ULONG CapturedOldProtectFor4k;
00234 ULONG OriginalProtectionMask;
00235 ULONG AltFlags;
00236
#endif
00237
00238
PAGED_CODE();
00239
00240 Attached =
FALSE;
00241
00242
00243
00244
00245
00246
#if defined (_WIN64)
00247
00248
if (ZeroBits >= 32) {
00249
00250
00251
00252
00253
00254 ZeroBits = 64 -
RtlFindMostSignificantBit (ZeroBits);
00255 }
00256
else if (ZeroBits) {
00257 ZeroBits += 32;
00258 }
00259
00260
#endif
00261
00262
if (ZeroBits >
MM_MAXIMUM_ZERO_BITS) {
00263
return STATUS_INVALID_PARAMETER_3;
00264 }
00265
00266
00267
00268
00269
00270
if ((AllocationType & ~(MEM_COMMIT | MEM_RESERVE | MEM_PHYSICAL |
00271 MEM_TOP_DOWN | MEM_RESET | MEM_WRITE_WATCH)) != 0) {
00272
return STATUS_INVALID_PARAMETER_5;
00273 }
00274
00275
00276
00277
00278
00279
if ((AllocationType & (MEM_COMMIT | MEM_RESERVE | MEM_RESET)) == 0) {
00280
return STATUS_INVALID_PARAMETER_5;
00281 }
00282
00283
if ((AllocationType & MEM_RESET) && (AllocationType != MEM_RESET)) {
00284
00285
00286
00287
00288
00289
return STATUS_INVALID_PARAMETER_5;
00290 }
00291
00292
if (AllocationType & MEM_WRITE_WATCH) {
00293
00294
00295
00296
00297
00298
if ((AllocationType & MEM_RESERVE) == 0) {
00299
return STATUS_INVALID_PARAMETER_5;
00300 }
00301
00302
if (
MmSupportWriteWatch ==
FALSE) {
00303
return STATUS_NOT_SUPPORTED;
00304 }
00305 }
00306
00307
if (AllocationType & MEM_PHYSICAL) {
00308
00309
00310
00311
00312
00313
00314
if (AllocationType != (MEM_RESERVE | MEM_PHYSICAL)) {
00315
return STATUS_INVALID_PARAMETER_5;
00316 }
00317
00318
if (Protect != PAGE_READWRITE) {
00319
return STATUS_INVALID_PARAMETER_6;
00320 }
00321 }
00322
00323
00324
00325
00326
00327
try {
00328 ProtectionMask =
MiMakeProtectionMask (Protect);
00329 } except (EXCEPTION_EXECUTE_HANDLER) {
00330
return GetExceptionCode();
00331 }
00332
00333 ChangeProtection =
FALSE;
00334
00335 PreviousMode = KeGetPreviousMode();
00336
00337
00338
00339
00340
00341
00342
try {
00343
00344
if (PreviousMode !=
KernelMode) {
00345
00346
ProbeForWritePointer (BaseAddress);
00347
ProbeForWriteUlong_ptr (RegionSize);
00348 }
00349
00350
00351
00352
00353
00354 CapturedBase = *BaseAddress;
00355
00356
00357
00358
00359
00360 CapturedRegionSize = *RegionSize;
00361
00362 } except (
ExSystemExceptionFilter()) {
00363
00364
00365
00366
00367
00368
00369
00370
return GetExceptionCode();
00371 }
00372
00373
#if defined(_MIALT4K_)
00374
00375 OriginalBase = CapturedBase;
00376 OriginalRegionSize = CapturedRegionSize;
00377
00378
#endif
00379
00380
#if DBG
00381
if (MmDebug &
MM_DBG_SHOW_NT_CALLS) {
00382
if ( MmWatchProcess ) {
00383 ;
00384 }
else {
00385
DbgPrint(
"allocvm process handle %lx base address %lx zero bits %lx\n",
00386 ProcessHandle, CapturedBase, ZeroBits);
00387
DbgPrint(
" region size %lx alloc type %lx protect %lx\n",
00388 CapturedRegionSize, AllocationType, Protect);
00389 }
00390 }
00391
#endif
00392
00393
00394
00395
00396
00397
00398
if (CapturedBase >
MM_HIGHEST_VAD_ADDRESS) {
00399
00400
00401
00402
00403
00404
return STATUS_INVALID_PARAMETER_2;
00405 }
00406
00407
if ((((ULONG_PTR)
MM_HIGHEST_VAD_ADDRESS + 1) - (ULONG_PTR)CapturedBase) <
00408 CapturedRegionSize) {
00409
00410
00411
00412
00413
00414
return STATUS_INVALID_PARAMETER_4;
00415 }
00416
00417
if (CapturedRegionSize == 0) {
00418
00419
00420
00421
00422
00423
return STATUS_INVALID_PARAMETER_4;
00424 }
00425
00426
00427
00428
00429
00430
if ( ProcessHandle == NtCurrentProcess() ) {
00431 Process =
PsGetCurrentProcess();
00432 }
else {
00433
Status =
ObReferenceObjectByHandle ( ProcessHandle,
00434 PROCESS_VM_OPERATION,
00435 PsProcessType,
00436 PreviousMode,
00437 (PVOID *)&Process,
00438 NULL );
00439
00440
if (!
NT_SUCCESS(Status)) {
00441
return Status;
00442 }
00443 }
00444
00445
00446
00447
00448
00449
00450
if (
PsGetCurrentProcess() != Process) {
00451
KeAttachProcess (&Process->
Pcb);
00452 Attached =
TRUE;
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
LOCK_WS_AND_ADDRESS_SPACE (Process);
00464
00465
00466
00467
00468
00469
if (Process->
AddressSpaceDeleted != 0) {
00470
Status = STATUS_PROCESS_IS_TERMINATING;
00471
goto ErrorReturn;
00472 }
00473
00474
if ((CapturedBase ==
NULL) || (AllocationType & MEM_RESERVE)) {
00475
00476
00477
00478
00479
00480
if ((Protect & PAGE_WRITECOPY) ||
00481 (Protect & PAGE_EXECUTE_WRITECOPY)) {
00482
Status = STATUS_INVALID_PAGE_PROTECTION;
00483
goto ErrorReturn;
00484 }
00485
00486
00487
00488
00489
00490
if (CapturedBase ==
NULL) {
00491
00492
00493
00494
00495
00496
00497 CapturedRegionSize =
ROUND_TO_PAGES (CapturedRegionSize);
00498
00499
00500
00501
00502
00503
00504
if (ZeroBits != 0) {
00505 TopAddress = (PVOID)(((ULONG_PTR)
MM_USER_ADDRESS_RANGE_LIMIT) >> ZeroBits);
00506
00507
00508
00509
00510
00511
00512
if (TopAddress >
MM_HIGHEST_VAD_ADDRESS) {
00513
Status = STATUS_INVALID_PARAMETER_3;
00514
goto ErrorReturn;
00515 }
00516
00517 }
else {
00518 TopAddress = (PVOID)
MM_HIGHEST_VAD_ADDRESS;
00519 }
00520
00521
#if defined (_WIN64)
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531 AllocationType |= MEM_TOP_DOWN;
00532
00533
#endif
00534
00535
00536
00537
00538
00539
try {
00540
00541
if (AllocationType & MEM_TOP_DOWN) {
00542
00543
00544
00545
00546
00547 StartingAddress =
MiFindEmptyAddressRangeDown (
00548 CapturedRegionSize,
00549 TopAddress,
00550 X64K);
00551
00552 }
else {
00553
00554 StartingAddress =
MiFindEmptyAddressRange (
00555 CapturedRegionSize,
00556 X64K,
00557 (ULONG)ZeroBits );
00558 }
00559
00560 } except (EXCEPTION_EXECUTE_HANDLER) {
00561
Status = GetExceptionCode();
00562
goto ErrorReturn;
00563 }
00564
00565
00566
00567
00568
00569 EndingAddress = (PVOID)(((ULONG_PTR)StartingAddress +
00570 CapturedRegionSize - 1
L) | (
PAGE_SIZE - 1
L));
00571
00572
if (EndingAddress > TopAddress) {
00573
00574
00575
00576
00577
00578
Status = STATUS_NO_MEMORY;
00579
goto ErrorReturn;
00580 }
00581
00582 }
else {
00583
00584
00585
00586
00587
00588
00589
00590 EndingAddress = (PVOID)(((ULONG_PTR)CapturedBase +
00591 CapturedRegionSize - 1
L) | (
PAGE_SIZE - 1
L));
00592
00593
00594
00595
00596
00597 StartingAddress = (PVOID)
MI_64K_ALIGN(CapturedBase);
00598
00599
00600
00601
00602
00603
if (
MiCheckForConflictingVad (StartingAddress, EndingAddress) !=
00604 (
PMMVAD)
NULL) {
00605
00606
Status = STATUS_CONFLICTING_ADDRESSES;
00607
goto ErrorReturn;
00608 }
00609 }
00610
00611
00612
00613
00614
00615
if (AllocationType & MEM_COMMIT) {
00616 QuotaCharge =
BYTES_TO_PAGES ((PCHAR)EndingAddress -
00617 (PCHAR)StartingAddress);
00618
00619 }
else {
00620 QuotaCharge = 0;
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630 BitMapSize = 0;
00631
00632
if (AllocationType & MEM_PHYSICAL) {
00633
00634
if (AllocationType & MEM_WRITE_WATCH) {
00635
Status = STATUS_INVALID_PARAMETER_5;
00636
goto ErrorReturn;
00637 }
00638
00639 PhysicalView = (
PMI_PHYSICAL_VIEW)
ExAllocatePoolWithTag (
00640 NonPagedPool,
00641
sizeof(
MI_PHYSICAL_VIEW),
00642 MI_PHYSICAL_VIEW_KEY);
00643
00644
if (PhysicalView ==
NULL) {
00645
Status = STATUS_INSUFFICIENT_RESOURCES;
00646
goto ErrorReturn;
00647 }
00648 }
00649
else if (AllocationType & MEM_WRITE_WATCH) {
00650
00651
ASSERT (AllocationType & MEM_RESERVE);
00652
00653 BitMapBits =
BYTES_TO_PAGES ((PCHAR)EndingAddress -
00654 (PCHAR)StartingAddress);
00655
00656 BitMapSize =
sizeof(RTL_BITMAP) + (ULONG)(((BitMapBits + 31) / 32) * 4);
00657
00658
BitMap =
ExAllocatePoolWithTag (NonPagedPool, BitMapSize, 'wwmM');
00659
00660
if (
BitMap ==
NULL) {
00661
Status = STATUS_INSUFFICIENT_RESOURCES;
00662
goto ErrorReturn;
00663 }
00664
00665
try {
00666
00667
00668
00669
00670
00671
00672
00673
PsChargePoolQuota (Process, NonPagedPool, BitMapSize);
00674
00675 } except (EXCEPTION_EXECUTE_HANDLER) {
00676
Status = GetExceptionCode();
00677
ExFreePool (BitMap);
00678
goto ErrorReturn;
00679 }
00680
00681 PhysicalView = (
PMI_PHYSICAL_VIEW)
ExAllocatePoolWithTag (
00682 NonPagedPool,
00683
sizeof(
MI_PHYSICAL_VIEW),
00684 MI_WRITEWATCH_VIEW_KEY);
00685
00686
if (PhysicalView ==
NULL) {
00687
ExFreePool (BitMap);
00688
PsReturnPoolQuota (Process, NonPagedPool, BitMapSize);
00689
Status = STATUS_INSUFFICIENT_RESOURCES;
00690
goto ErrorReturn;
00691 }
00692
00693
RtlInitializeBitMap (BitMap,
00694 (PULONG)(BitMap + 1),
00695 BitMapBits);
00696
00697
RtlClearAllBits (BitMap);
00698 }
00699
00700 Vad =
ExAllocatePoolWithTag (NonPagedPool,
00701
sizeof(
MMVAD_SHORT),
00702 'SdaV');
00703
00704
try {
00705
00706
if (Vad ==
NULL) {
00707
ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
00708 }
00709
00710 Vad->
StartingVpn =
MI_VA_TO_VPN (StartingAddress);
00711 Vad->
EndingVpn =
MI_VA_TO_VPN (EndingAddress);
00712
00713 Vad->
u.LongFlags = 0;
00714
if (AllocationType & MEM_COMMIT) {
00715 Vad->
u.VadFlags.MemCommit = 1;
00716 }
00717
00718
if (AllocationType & MEM_PHYSICAL) {
00719 Vad->
u.VadFlags.UserPhysicalPages = 1;
00720 }
00721
00722 Vad->
u.VadFlags.Protection = ProtectionMask;
00723 Vad->
u.VadFlags.PrivateMemory = 1;
00724
00725 Vad->
u.VadFlags.CommitCharge = QuotaCharge;
00726
00727
MiInsertVad (Vad);
00728
00729 } except (EXCEPTION_EXECUTE_HANDLER) {
00730
00731
if (Vad != (
PMMVAD)
NULL) {
00732
00733
00734
00735
00736
00737
00738
00739
ExFreePool (Vad);
00740
Status = GetExceptionCode();
00741
00742 }
else {
00743
Status = STATUS_INSUFFICIENT_RESOURCES;
00744 }
00745
00746
if (AllocationType & MEM_PHYSICAL) {
00747
ExFreePool (PhysicalView);
00748 }
00749
else if (BitMapSize != 0) {
00750
ExFreePool (PhysicalView);
00751
ExFreePool (BitMap);
00752
PsReturnPoolQuota (Process, NonPagedPool, BitMapSize);
00753 }
00754
00755
goto ErrorReturn;
00756 }
00757
00758
00759
00760
00761
00762
if (AllocationType & MEM_PHYSICAL) {
00763
00764
if (
MiCreatePageTablesForPhysicalRange (Process,
00765 StartingAddress,
00766 EndingAddress) ==
FALSE) {
00767
00768
MiRemoveVad (Vad);
00769
ExFreePool (Vad);
00770
ExFreePool (PhysicalView);
00771
Status = STATUS_INSUFFICIENT_RESOURCES;
00772
goto ErrorReturn;
00773 }
00774
00775 PhysicalView->
Vad = Vad;
00776 PhysicalView->
StartVa = StartingAddress;
00777 PhysicalView->
EndVa = EndingAddress;
00778
00779
00780
00781
00782
00783
00784
MiPhysicalViewInserter (Process, PhysicalView);
00785 }
00786
else if (BitMapSize != 0) {
00787
00788 Vad->
u.VadFlags.WriteWatch = 1;
00789
00790 PhysicalView->
Vad = Vad;
00791 PhysicalView->
StartVa = StartingAddress;
00792 PhysicalView->
EndVa = EndingAddress;
00793 PhysicalView->
BitMap =
BitMap;
00794
00795
MiPhysicalViewInserter (Process, PhysicalView);
00796 }
00797
00798
00799
00800
00801
00802
UNLOCK_WS_UNSAFE (Process);
00803
00804
00805
00806
00807
00808
00809 CapturedRegionSize = (PCHAR)EndingAddress - (PCHAR)StartingAddress + 1
L;
00810 Process->
VirtualSize += CapturedRegionSize;
00811
00812
if (Process->
VirtualSize > Process->
PeakVirtualSize) {
00813 Process->
PeakVirtualSize = Process->
VirtualSize;
00814 }
00815
00816
#if defined(_MIALT4K_)
00817
00818
if (Process->
Wow64Process !=
NULL) {
00819
00820
if (OriginalBase ==
NULL) {
00821
00822 OriginalRegionSize =
ROUND_TO_4K_PAGES(OriginalRegionSize);
00823
00824 EndingAddress = (PVOID)(((ULONG_PTR) StartingAddress +
00825 OriginalRegionSize - 1
L) | (
PAGE_4K - 1
L));
00826
00827 }
else {
00828
00829 EndingAddress = (PVOID)(((ULONG_PTR)OriginalBase +
00830 OriginalRegionSize - 1
L) | (
PAGE_4K - 1
L));
00831 }
00832
00833 CapturedRegionSize = (PCHAR)EndingAddress - (PCHAR)StartingAddress + 1
L;
00834
00835
00836
00837
00838
00839 AltFlags = (AllocationType & MEM_COMMIT) ?
ALT_COMMIT : 0;
00840
00841
MiProtectFor4kPage (StartingAddress,
00842 CapturedRegionSize,
00843 ProtectionMask,
00844 ALT_ALLOCATE|AltFlags,
00845 Process);
00846 }
00847
00848
#endif
00849
00850
00851
00852
00853
00854
00855
UNLOCK_ADDRESS_SPACE(Process);
00856
if (Attached) {
00857
KeDetachProcess();
00858 }
00859
00860
if (ProcessHandle != NtCurrentProcess()) {
00861
ObDereferenceObject (Process);
00862 }
00863
00864
00865
00866
00867
00868
00869
try {
00870
00871 *RegionSize = CapturedRegionSize;
00872 *BaseAddress = StartingAddress;
00873
00874 } except (EXCEPTION_EXECUTE_HANDLER) {
00875
00876
00877
00878
00879
00880
00881 NOTHING;
00882 }
00883
00884
#if DBG
00885
if (MmDebug &
MM_DBG_SHOW_NT_CALLS) {
00886
if ( MmWatchProcess ) {
00887
if ( MmWatchProcess ==
PsGetCurrentProcess() ) {
00888
DbgPrint(
"\n+++ ALLOC Type %lx Base %lx Size %lx\n",
00889 AllocationType,StartingAddress, CapturedRegionSize);
00890 MmFooBar();
00891 }
00892 }
else {
00893
DbgPrint(
"return allocvm status %lx baseaddr %lx size %lx\n",
00894 Status, StartingAddress, CapturedRegionSize);
00895 }
00896 }
00897
#endif
00898
00899
return STATUS_SUCCESS;
00900
00901 }
else {
00902
00903
00904
00905
00906
00907
00908
if (AllocationType == MEM_RESET) {
00909
00910
00911
00912
00913
00914 EndingAddress = (PVOID)((ULONG_PTR)
PAGE_ALIGN ((ULONG_PTR)CapturedBase +
00915 CapturedRegionSize) - 1);
00916 StartingAddress = (PVOID)
PAGE_ALIGN((PUCHAR)CapturedBase + PAGE_SIZE - 1);
00917
if (StartingAddress > EndingAddress) {
00918
Status = STATUS_CONFLICTING_ADDRESSES;
00919
goto ErrorReturn;
00920 }
00921 }
else {
00922 EndingAddress = (PVOID)(((ULONG_PTR)CapturedBase +
00923 CapturedRegionSize - 1) | (
PAGE_SIZE - 1));
00924 StartingAddress = (PVOID)
PAGE_ALIGN(CapturedBase);
00925 }
00926
00927 CapturedRegionSize = (PCHAR)EndingAddress - (PCHAR)StartingAddress + 1;
00928
00929 FoundVad =
MiCheckForConflictingVad (StartingAddress, EndingAddress);
00930
00931
#if defined(_MIALT4K_)
00932
00933
if (Process->
Wow64Process !=
NULL) {
00934
00935 EmulationFor4kPage =
TRUE;
00936
00937 OriginalProtectionMask =
MiMakeProtectionMask(Protect);
00938
00939
00940
00941
00942
00943
if (FoundVad->
u.VadFlags.NoChange == 0) {
00944
00945 Protect =
MiMakeProtectForNativePage(StartingAddress,
00946 Protect,
00947 Process);
00948
00949 ProtectionMask =
MiMakeProtectionMask (Protect);
00950 }
00951
00952 }
00953
00954
#endif
00955
00956
if (FoundVad == (
PMMVAD)
NULL) {
00957
00958
00959
00960
00961
00962
00963
Status = STATUS_CONFLICTING_ADDRESSES;
00964
goto ErrorReturn;
00965 }
00966
00967
if (FoundVad->
u.VadFlags.UserPhysicalPages == 1) {
00968
Status = STATUS_CONFLICTING_ADDRESSES;
00969
goto ErrorReturn;
00970 }
00971
00972
if (FoundVad->
u.VadFlags.CommitCharge ==
MM_MAX_COMMIT) {
00973
00974
00975
00976
00977
00978
Status = STATUS_CONFLICTING_ADDRESSES;
00979
goto ErrorReturn;
00980 }
00981
00982
00983
00984
00985
00986
00987
if ((
MI_VA_TO_VPN (StartingAddress) < FoundVad->
StartingVpn) ||
00988 (
MI_VA_TO_VPN (EndingAddress) > FoundVad->
EndingVpn)) {
00989
00990
00991
00992
00993
00994
00995
Status = STATUS_CONFLICTING_ADDRESSES;
00996
goto ErrorReturn;
00997 }
00998
00999
if (AllocationType == MEM_RESET) {
01000
Status =
MiResetVirtualMemory (StartingAddress,
01001 EndingAddress,
01002 FoundVad,
01003 Process);
01004
goto done;
01005
01006 }
else if (FoundVad->
u.VadFlags.PrivateMemory == 0) {
01007
01008
01009
01010
01011
01012
01013
if (Protect & PAGE_NOCACHE) {
01014
Status = STATUS_INVALID_PAGE_PROTECTION;
01015
goto ErrorReturn;
01016 }
01017
01018
if (FoundVad->
u.VadFlags.NoChange == 1) {
01019
01020
01021
01022
01023
01024
01025
Status =
MiCheckSecuredVad (FoundVad,
01026 CapturedBase,
01027 CapturedRegionSize,
01028 ProtectionMask);
01029
01030
if (!
NT_SUCCESS (Status)) {
01031
goto ErrorReturn;
01032 }
01033 }
01034
01035
if (FoundVad->
ControlArea->
FilePointer !=
NULL) {
01036
if (FoundVad->
u2.VadFlags2.ExtendableFile == 0) {
01037
01038
01039
01040
01041
01042
Status = STATUS_ALREADY_COMMITTED;
01043
goto ErrorReturn;
01044 }
else {
01045
01046
01047
01048
01049
01050
SECTION Section;
01051 LARGE_INTEGER NewSize;
01052
PCONTROL_AREA ControlArea;
01053
01054 RtlZeroMemory (&Section,
sizeof(
SECTION));
01055 ControlArea = FoundVad->
ControlArea;
01056 Section.
Segment = ControlArea->
Segment;
01057 Section.
u.LongFlags = ControlArea->
u.LongFlags;
01058 Section.
InitialPageProtection = PAGE_READWRITE;
01059 NewSize.QuadPart = FoundVad->
u2.VadFlags2.FileOffset;
01060 NewSize.QuadPart = NewSize.QuadPart << 16;
01061 NewSize.QuadPart += 1 +
01062 ((PCHAR)EndingAddress - (PCHAR)
MI_VPN_TO_VA (FoundVad->
StartingVpn));
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
MiFlushAcquire (ControlArea);
01074
01075
UNLOCK_WS_AND_ADDRESS_SPACE (Process);
01076
01077
Status =
MmExtendSection (&Section,
01078 &NewSize,
01079 FALSE);
01080
01081
MiFlushRelease (ControlArea);
01082
01083
if (
NT_SUCCESS(Status)) {
01084
01085
LOCK_WS_AND_ADDRESS_SPACE (Process);
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
if (Process->
AddressSpaceDeleted != 0) {
01098
01099
goto ErrorReturn;
01100 }
01101
01102 FoundVad =
MiCheckForConflictingVad (StartingAddress,
01103 EndingAddress);
01104
01105
if (FoundVad == (
PMMVAD)
NULL) {
01106
01107
01108
01109
01110
01111
01112
01113
goto ErrorReturn;
01114 }
01115
01116
if (ControlArea != FoundVad->
ControlArea) {
01117
goto ErrorReturn;
01118 }
01119
01120
if (FoundVad->
u.VadFlags.UserPhysicalPages == 1) {
01121
01122
01123
goto ErrorReturn;
01124 }
01125
01126
if (FoundVad->
u.VadFlags.CommitCharge ==
MM_MAX_COMMIT) {
01127
01128
01129
01130
01131
01132
goto ErrorReturn;
01133 }
01134
01135
01136
01137
01138
01139
01140
if ((
MI_VA_TO_VPN (StartingAddress) < FoundVad->
StartingVpn) ||
01141 (
MI_VA_TO_VPN (EndingAddress) > FoundVad->
EndingVpn)) {
01142
01143
01144
01145
01146
01147
01148
01149
goto ErrorReturn;
01150 }
01151
01152
if (FoundVad->
u.VadFlags.NoChange == 1) {
01153
01154
01155
01156
01157
01158
01159
NTSTATUS Status2;
01160
01161 Status2 =
MiCheckSecuredVad (FoundVad,
01162 CapturedBase,
01163 CapturedRegionSize,
01164 ProtectionMask);
01165
01166
if (!
NT_SUCCESS (Status2)) {
01167
goto ErrorReturn;
01168 }
01169 }
01170
01171
if (FoundVad->
ControlArea->
FilePointer ==
NULL) {
01172
goto ErrorReturn;
01173 }
01174
01175
if (FoundVad->
u2.VadFlags2.ExtendableFile == 0) {
01176
goto ErrorReturn;
01177 }
01178
01179
#if defined(_MIALT4K_)
01180
01181
if (EmulationFor4kPage ==
TRUE) {
01182
01183
UNLOCK_WS_UNSAFE(Process);
01184
01185 StartingAddressFor4k = (PVOID)
PAGE_4K_ALIGN(OriginalBase);
01186
01187 EndingAddressFor4k = (PVOID)(((ULONG_PTR)OriginalBase +
01188 OriginalRegionSize - 1) | (
PAGE_4K - 1));
01189
01190 CapturedRegionSizeFor4k = (ULONG_PTR)EndingAddressFor4k -
01191 (ULONG_PTR)StartingAddressFor4k + 1
L;
01192
01193
if ((FoundVad->
u.VadFlags.ImageMap == 1) ||
01194 (FoundVad->
u2.VadFlags2.CopyOnWrite == 1)) {
01195
01196 OriginalProtectionMask |=
MM_PROTECTION_COPY_MASK;
01197
01198 }
01199
01200
MiProtectFor4kPage (StartingAddressFor4k,
01201 CapturedRegionSizeFor4k,
01202 OriginalProtectionMask,
01203 ALT_COMMIT,
01204 Process);
01205
01206
LOCK_WS_UNSAFE(Process);
01207 }
01208
01209
#endif
01210
01211
try {
01212
MiSetProtectionOnSection (Process,
01213 FoundVad,
01214 StartingAddress,
01215 EndingAddress,
01216 Protect,
01217 &OldProtect,
01218 TRUE);
01219 } except (EXCEPTION_EXECUTE_HANDLER) {
01220 NOTHING;
01221 }
01222
01223
UNLOCK_WS_AND_ADDRESS_SPACE (Process);
01224 }
01225
01226
goto ErrorReturn1;
01227 }
01228 }
01229
01230 StartingPte =
MiGetProtoPteAddress (FoundVad,
01231
MI_VA_TO_VPN(StartingAddress));
01232 PointerPte = StartingPte;
01233 LastPte =
MiGetProtoPteAddress (FoundVad,
01234
MI_VA_TO_VPN(EndingAddress));
01235
01236
UNLOCK_WS_UNSAFE (Process);
01237
01238
ExAcquireFastMutexUnsafe (&MmSectionCommitMutex);
01239
01240
#if 0
01241
if (AllocationType &
MEM_CHECK_COMMIT_STATE) {
01242
01243
01244
01245
01246
01247
while (PointerPte <= LastPte) {
01248
01249
01250
01251
01252
01253
01254
01255
01256
if (PointerPte->
u.Long != 0) {
01257
ExReleaseFastMutexUnsafe (&MmSectionCommitMutex);
01258
Status = STATUS_ALREADY_COMMITTED;
01259
UNLOCK_ADDRESS_SPACE (Process);
01260
goto ErrorReturn1;
01261 }
01262 PointerPte += 1;
01263 }
01264 }
01265
#endif //0
01266
01267 PointerPte = StartingPte;
01268
01269
01270
01271
01272
01273
01274
01275 QuotaCharge = 1 + LastPte - StartingPte;
01276
01277 CopyOnWriteCharge = 0;
01278
01279
if (
MI_IS_PTE_PROTECTION_COPY_WRITE(ProtectionMask)) {
01280
01281
01282
01283
01284
01285
01286 CopyOnWriteCharge = QuotaCharge;
01287 }
01288
01289
01290
01291
01292
01293
01294 QuotaFree = 0;
01295 ChargedExactQuota =
FALSE;
01296
Status = STATUS_SUCCESS;
01297 ChargedJobCommit =
FALSE;
01298
01299
for (; ; ) {
01300
try {
01301 PageFileChargeSucceeded =
FALSE;
01302
01303
if (CopyOnWriteCharge != 0) {
01304
MiChargePageFileQuota (CopyOnWriteCharge, Process);
01305 }
01306
01307 PageFileChargeSucceeded =
TRUE;
01308
01309
01310
01311
01312
01313
01314
if (Process->
CommitChargeLimit) {
01315
if (Process->
CommitCharge + CopyOnWriteCharge > Process->
CommitChargeLimit) {
01316
if (Process->
Job) {
01317
PsReportProcessMemoryLimitViolation ();
01318 }
01319
ExRaiseStatus (STATUS_COMMITMENT_LIMIT);
01320 }
01321 }
01322
if (Process->
JobStatus &
PS_JOB_STATUS_REPORT_COMMIT_CHANGES) {
01323
if (
PsChangeJobMemoryUsage(CopyOnWriteCharge) ==
FALSE) {
01324
ExRaiseStatus (STATUS_COMMITMENT_LIMIT);
01325 }
01326 ChargedJobCommit =
TRUE;
01327 }
01328
01329
if (
MiChargeCommitment (QuotaCharge + CopyOnWriteCharge, NULL) ==
FALSE) {
01330
ExRaiseStatus (STATUS_COMMITMENT_LIMIT);
01331 }
01332
01333
MM_TRACK_COMMIT (MM_DBG_COMMIT_ALLOCVM1, QuotaCharge + CopyOnWriteCharge);
01334
01335
break;
01336
01337 } except (EXCEPTION_EXECUTE_HANDLER) {
01338
01339
01340
01341
01342
01343
01344
01345
if (PageFileChargeSucceeded && CopyOnWriteCharge != 0) {
01346
MiReturnPageFileQuota (CopyOnWriteCharge, Process);
01347 }
01348
01349
if (ChargedJobCommit ==
TRUE) {
01350
01351
01352
01353
01354
01355
01356
01357 Process->
CommitCharge += CopyOnWriteCharge;
01358
PsChangeJobMemoryUsage (-(SSIZE_T)CopyOnWriteCharge);
01359 Process->
CommitCharge -= CopyOnWriteCharge;
01360 }
01361
01362
if (
Status != STATUS_SUCCESS || PageFileChargeSucceeded ==
FALSE) {
01363
01364
01365
01366
01367
01368
01369
01370
ExReleaseFastMutexUnsafe (&MmSectionCommitMutex);
01371
UNLOCK_ADDRESS_SPACE (Process);
01372
goto ErrorReturn1;
01373 }
01374
01375
01376
01377
01378
01379
01380
01381
while (PointerPte <= LastPte) {
01382
01383
01384
01385
01386
01387
01388
01389
if (PointerPte->
u.Long != 0) {
01390 QuotaFree -= 1;
01391 }
01392 PointerPte += 1;
01393 }
01394
01395 PointerPte = StartingPte;
01396
01397 QuotaCharge += QuotaFree;
01398 ChargedExactQuota =
TRUE;
01399
Status = GetExceptionCode();
01400 }
01401 }
01402
01403 FoundVad->
ControlArea->
Segment->
NumberOfCommittedPages +=
01404 QuotaCharge;
01405
01406 FoundVad->
u.VadFlags.CommitCharge += CopyOnWriteCharge;
01407 Process->
CommitCharge += CopyOnWriteCharge;
01408
if (Process->
CommitCharge > Process->
CommitChargePeak) {
01409 Process->
CommitChargePeak = Process->
CommitCharge;
01410 }
01411
MmSharedCommit += QuotaCharge;
01412
01413
01414
01415
01416
01417 TempPte = FoundVad->
ControlArea->
Segment->
SegmentPteTemplate;
01418
01419 QuotaFree = 0;
01420
01421
while (PointerPte <= LastPte) {
01422
01423
if (PointerPte->
u.Long != 0) {
01424
01425
01426
01427
01428
01429 QuotaFree += 1;
01430 }
else {
01431
MI_WRITE_INVALID_PTE (PointerPte, TempPte);
01432 }
01433 PointerPte += 1;
01434 }
01435
01436
if (ChargedExactQuota ==
FALSE && QuotaFree != 0) {
01437
01438 FoundVad->
ControlArea->
Segment->
NumberOfCommittedPages -= QuotaFree;
01439
MmSharedCommit -= QuotaFree;
01440
ASSERT ((LONG)FoundVad->
ControlArea->
Segment->
NumberOfCommittedPages >= 0);
01441
01442
if (CopyOnWriteCharge != 0) {
01443 FoundVad->
u.VadFlags.CommitCharge -= QuotaFree;
01444
if (ChargedJobCommit ==
TRUE) {
01445
PsChangeJobMemoryUsage (-(SSIZE_T)QuotaFree);
01446 }
01447 Process->
CommitCharge -= QuotaFree;
01448
ExReleaseFastMutexUnsafe (&MmSectionCommitMutex);
01449
MiReturnPageFileQuota (QuotaFree, Process);
01450 }
01451
else {
01452
ExReleaseFastMutexUnsafe (&MmSectionCommitMutex);
01453 }
01454
01455
ASSERT ((SSIZE_T)FoundVad->
u.VadFlags.CommitCharge >= 0);
01456
01457
MiReturnCommitment (
01458 (CopyOnWriteCharge ? 2*QuotaFree : QuotaFree));
01459
01460
MM_TRACK_COMMIT (MM_DBG_COMMIT_RETURN_ALLOCVM1,
01461 (CopyOnWriteCharge ? 2*QuotaFree : QuotaFree));
01462 }
01463
else {
01464
ExReleaseFastMutexUnsafe (&MmSectionCommitMutex);
01465 }
01466
01467
#if defined(_MIALT4K_)
01468
01469
01470
01471
01472
01473
01474
if (EmulationFor4kPage ==
TRUE) {
01475
01476 StartingAddressFor4k = (PVOID)
PAGE_4K_ALIGN(OriginalBase);
01477
01478 EndingAddressFor4k = (PVOID)(((ULONG_PTR)OriginalBase +
01479 OriginalRegionSize - 1) | (
PAGE_4K - 1));
01480
01481 CapturedRegionSizeFor4k = (ULONG_PTR)EndingAddressFor4k -
01482 (ULONG_PTR)StartingAddressFor4k + 1
L;
01483
01484
if ((FoundVad->
u.VadFlags.ImageMap == 1) ||
01485 (FoundVad->
u2.VadFlags2.CopyOnWrite == 1)) {
01486
01487 OriginalProtectionMask |=
MM_PROTECTION_COPY_MASK;
01488
01489 }
01490
01491
01492
01493
01494
01495
MiProtectFor4kPage (StartingAddressFor4k,
01496 CapturedRegionSizeFor4k,
01497 OriginalProtectionMask,
01498 ALT_COMMIT,
01499 Process);
01500 }
01501
#endif
01502
01503
01504
01505
01506
01507
LOCK_WS_UNSAFE (Process);
01508
01509
try {
01510
MiSetProtectionOnSection (Process,
01511 FoundVad,
01512 StartingAddress,
01513 EndingAddress,
01514 Protect,
01515 &OldProtect,
01516 TRUE);
01517 } except (EXCEPTION_EXECUTE_HANDLER) {
01518 NOTHING;
01519 }
01520
01521
UNLOCK_WS_AND_ADDRESS_SPACE (Process);
01522
01523
if (Attached) {
01524
KeDetachProcess();
01525 }
01526
if ( ProcessHandle != NtCurrentProcess() ) {
01527
ObDereferenceObject (Process);
01528 }
01529
01530
try {
01531
01532 *RegionSize = CapturedRegionSize;
01533 *BaseAddress = StartingAddress;
01534
01535 } except (EXCEPTION_EXECUTE_HANDLER) {
01536
01537
01538
01539
01540
01541
01542 NOTHING;
01543 }
01544
01545
#if defined(_MIALT4K_)
01546
if (EmulationFor4kPage ==
TRUE) {
01547 CapturedRegionSize = CapturedRegionSizeFor4k;
01548 StartingAddress = StartingAddressFor4k;
01549 }
01550
#endif
01551
01552
#if DBG
01553
if (MmDebug &
MM_DBG_SHOW_NT_CALLS) {
01554
if ( MmWatchProcess ) {
01555
if ( MmWatchProcess ==
PsGetCurrentProcess() ) {
01556
DbgPrint(
"\n+++ ALLOC Type %lx Base %lx Size %lx\n",
01557 AllocationType,StartingAddress, CapturedRegionSize);
01558 MmFooBar();
01559 }
01560 }
else {
01561
DbgPrint(
"return allocvm status %lx baseaddr %lx size %lx\n",
01562 Status, CapturedRegionSize, StartingAddress);
01563 }
01564 }
01565
#endif
01566
01567
return STATUS_SUCCESS;
01568
01569 }
else {
01570
01571
01572
01573
01574
01575
if ((Protect & PAGE_WRITECOPY) ||
01576 (Protect & PAGE_EXECUTE_WRITECOPY)) {
01577
Status = STATUS_INVALID_PAGE_PROTECTION;
01578
goto ErrorReturn;
01579 }
01580
01581
01582
01583
01584
01585
#if 0
01586
if (AllocationType &
MEM_CHECK_COMMIT_STATE) {
01587
if ( !
MiIsEntireRangeDecommitted(StartingAddress,
01588 EndingAddress,
01589 FoundVad,
01590 Process)) {
01591
01592
01593
01594
01595
01596
01597
Status = STATUS_ALREADY_COMMITTED;
01598
goto ErrorReturn;
01599 }
01600 }
01601
#endif //0
01602
01603
01604
01605
01606
01607
01608
01609 PointerPpe =
MiGetPpeAddress (StartingAddress);
01610 PointerPde =
MiGetPdeAddress (StartingAddress);
01611 PointerPte =
MiGetPteAddress (StartingAddress);
01612 LastPte =
MiGetPteAddress (EndingAddress);
01613
01614
01615
01616
01617
01618 QuotaCharge = 1 + LastPte - PointerPte;
01619
01620
01621
01622
01623
01624
01625 QuotaFree = 0;
01626 ChargedExactQuota =
FALSE;
01627
Status = STATUS_SUCCESS;
01628 ChargedJobCommit =
FALSE;
01629
01630
for (; ; ) {
01631
try {
01632 PageFileChargeSucceeded =
FALSE;
01633
01634
if (Process->
CommitChargeLimit) {
01635
if (Process->
CommitCharge + QuotaCharge > Process->
CommitChargeLimit) {
01636
if (Process->
Job) {
01637
PsReportProcessMemoryLimitViolation ();
01638 }
01639
ExRaiseStatus (STATUS_COMMITMENT_LIMIT);
01640 }
01641 }
01642
if (Process->
JobStatus &
PS_JOB_STATUS_REPORT_COMMIT_CHANGES) {
01643
if (
PsChangeJobMemoryUsage(QuotaCharge) ==
FALSE) {
01644
ExRaiseStatus (STATUS_COMMITMENT_LIMIT);
01645 }
01646 ChargedJobCommit =
TRUE;
01647 }
01648
01649
if (
MiChargeCommitment (QuotaCharge, Process) ==
FALSE) {
01650
ExRaiseStatus (STATUS_COMMITMENT_LIMIT);
01651 }
01652
01653
MM_TRACK_COMMIT (MM_DBG_COMMIT_ALLOCVM2, QuotaCharge);
01654
01655 PageFileChargeSucceeded =
TRUE;
01656
MiChargePageFileQuota (QuotaCharge, Process);
01657
01658 FoundVad->
u.VadFlags.CommitCharge += QuotaCharge;
01659 Process->
CommitCharge += QuotaCharge;
01660
if (Process->
CommitCharge > Process->
CommitChargePeak) {
01661 Process->
CommitChargePeak = Process->
CommitCharge;
01662 }
01663
break;
01664
01665 } except (EXCEPTION_EXECUTE_HANDLER) {
01666
01667
01668
01669
01670
01671
01672
01673
if (ChargedJobCommit ==
TRUE) {
01674
01675
01676
01677
01678
01679
01680
01681 Process->
CommitCharge += QuotaCharge;
01682
PsChangeJobMemoryUsage (-QuotaCharge);
01683 Process->
CommitCharge -= QuotaCharge;
01684 }
01685
01686
if (PageFileChargeSucceeded) {
01687
MiReturnCommitment (QuotaCharge);
01688
MM_TRACK_COMMIT (MM_DBG_COMMIT_RETURN_ALLOCVM2, QuotaCharge);
01689 }
01690
01691
if (
Status != STATUS_SUCCESS) {
01692
01693
01694
01695
01696
01697
01698
goto ErrorReturn;
01699 }
01700
01701
Status = GetExceptionCode();
01702
01703
01704
01705
01706
01707
01708
01709 QuotaFree = -(LONG)
MiCalculatePageCommitment (
01710 StartingAddress,
01711 EndingAddress,
01712 FoundVad,
01713 Process);
01714
01715
if (QuotaFree == 0) {
01716
goto ErrorReturn;
01717 }
01718
01719 ChargedExactQuota =
TRUE;
01720 QuotaCharge += QuotaFree;
01721
ASSERT (QuotaCharge >= 0);
01722 }
01723 }
01724
01725
01726
01727
01728
01729
01730 TempPte =
ZeroPte;
01731 TempPte.
u.Soft.Protection = ProtectionMask;
01732
01733 DecommittedPte =
ZeroPte;
01734 DecommittedPte.
u.Soft.Protection =
MM_DECOMMIT;
01735
01736
01737
01738
01739
01740
01741
#if defined (_WIN64)
01742
MiMakePpeExistAndMakeValid (PointerPpe, Process, FALSE);
01743
if (PointerPde->
u.Long == 0) {
01744 UsedPageDirectoryHandle =
MI_GET_USED_PTES_HANDLE (PointerPte);
01745
MI_INCREMENT_USED_PTES_BY_HANDLE (UsedPageDirectoryHandle);
01746 }
01747
#endif
01748
01749
MiMakePdeExistAndMakeValid (PointerPde, Process, FALSE);
01750
01751
if (FoundVad->
u.VadFlags.MemCommit) {
01752 CommitLimitPte =
MiGetPteAddress (MI_VPN_TO_VA (FoundVad->
EndingVpn));
01753 }
else {
01754 CommitLimitPte =
NULL;
01755 }
01756
01757 QuotaFree = 0;
01758
01759
while (PointerPte <= LastPte) {
01760
01761
if (
MiIsPteOnPdeBoundary (PointerPte)) {
01762
01763 PointerPde =
MiGetPteAddress (PointerPte);
01764 PointerPpe =
MiGetPteAddress (PointerPde);
01765
01766
if (
MiIsPteOnPpeBoundary (PointerPte)) {
01767
MiMakePpeExistAndMakeValid (PointerPpe, Process, FALSE);
01768 }
01769
01770
#if defined (_WIN64)
01771
if (PointerPde->
u.Long == 0) {
01772
MI_WRITE_INVALID_PTE (PointerPde, TempPte);
01773 UsedPageDirectoryHandle =
MI_GET_USED_PTES_HANDLE (PointerPte);
01774
01775
MI_INCREMENT_USED_PTES_BY_HANDLE (UsedPageDirectoryHandle);
01776 }
01777
#endif
01778
01779
01780
01781
01782
01783
01784
MiMakePdeExistAndMakeValid (PointerPde, Process, FALSE);
01785 }
01786
01787
if (PointerPte->u.Long == 0) {
01788
01789
if (PointerPte <= CommitLimitPte) {
01790
01791
01792
01793
01794
01795 QuotaFree += 1;
01796
01797 }
01798
01799
MI_WRITE_INVALID_PTE (PointerPte, TempPte);
01800
01801
01802
01803
01804
01805
01806
01807 Va =
MiGetVirtualAddressMappedByPte (PointerPte);
01808 UsedPageTableHandle =
MI_GET_USED_PTES_HANDLE (Va);
01809
01810
MI_INCREMENT_USED_PTES_BY_HANDLE (UsedPageTableHandle);
01811 }
else {
01812
if (PointerPte->u.Long == DecommittedPte.
u.Long) {
01813
01814
01815
01816
01817
01818
MI_WRITE_INVALID_PTE (PointerPte, TempPte);
01819 }
else {
01820 QuotaFree += 1;
01821
01822
01823
01824
01825
01826
01827
if (!ChangeProtection &&
01828 (Protect !=
MiGetPageProtection (PointerPte,
01829 Process))) {
01830 ChangeProtection =
TRUE;
01831 }
01832 }
01833 }
01834 PointerPte += 1;
01835 }
01836 }
01837
01838
if (ChargedExactQuota ==
FALSE && QuotaFree != 0) {
01839
ASSERT (QuotaFree >= 0);
01840
MiReturnCommitment (QuotaFree);
01841
MM_TRACK_COMMIT (MM_DBG_COMMIT_RETURN_ALLOCVM3, QuotaFree);
01842
MiReturnPageFileQuota (QuotaFree, Process);
01843 FoundVad->
u.VadFlags.CommitCharge -= QuotaFree;
01844
if (ChargedJobCommit) {
01845
PsChangeJobMemoryUsage (-(SSIZE_T)QuotaFree);
01846 }
01847 Process->
CommitCharge -= QuotaFree;
01848
ASSERT (FoundVad->
u.VadFlags.CommitCharge >= 0);
01849 }
01850
#if defined(_MIALT4K_)
01851
01852
if (EmulationFor4kPage ==
TRUE) {
01853
01854
UNLOCK_WS_UNSAFE (Process);
01855
01856 StartingAddress = (PVOID)
PAGE_4K_ALIGN(OriginalBase);
01857
01858 EndingAddress = (PVOID)(((ULONG_PTR)OriginalBase +
01859 OriginalRegionSize - 1) | (
PAGE_4K - 1));
01860
01861 CapturedRegionSize = (ULONG_PTR)EndingAddress -
01862 (ULONG_PTR)StartingAddress + 1
L;
01863
01864
01865
01866
01867
MiProtectFor4kPage (StartingAddress,
01868 CapturedRegionSize,
01869 OriginalProtectionMask,
01870 ALT_COMMIT,
01871 Process);
01872
01873
LOCK_WS_UNSAFE (Process);
01874 }
01875
#endif
01876
01877
01878
01879
01880
01881
01882
01883 done:
01884
UNLOCK_WS_AND_ADDRESS_SPACE (Process);
01885
01886
if (ChangeProtection) {
01887 PVOID
Start;
01888 SIZE_T
Size;
01889 ULONG LastProtect;
01890
01891
Start = StartingAddress;
01892
Size = CapturedRegionSize;
01893
MiProtectVirtualMemory (Process,
01894 &Start,
01895 &Size,
01896 Protect,
01897 &LastProtect);
01898 }
01899
01900
if (Attached) {
01901
KeDetachProcess();
01902 }
01903
if ( ProcessHandle != NtCurrentProcess() ) {
01904
ObDereferenceObject (Process);
01905 }
01906
01907
01908
01909
01910
01911
01912
try {
01913
01914 *RegionSize = CapturedRegionSize;
01915 *BaseAddress = StartingAddress;
01916
01917 } except (EXCEPTION_EXECUTE_HANDLER) {
01918
return GetExceptionCode();
01919 }
01920
01921
#if DBG
01922
if (MmDebug &
MM_DBG_SHOW_NT_CALLS) {
01923
if ( MmWatchProcess ) {
01924
if ( MmWatchProcess ==
PsGetCurrentProcess() ) {
01925
DbgPrint(
"\n+++ ALLOC Type %lx Base %lx Size %lx\n",
01926 AllocationType,StartingAddress, CapturedRegionSize);
01927 MmFooBar();
01928 }
01929 }
else {
01930
DbgPrint(
"return allocvm status %lx baseaddr %lx size %lx\n",
01931 Status, CapturedRegionSize, StartingAddress);
01932 }
01933 }
01934
#endif
01935
01936
return STATUS_SUCCESS;
01937 }
01938
01939 ErrorReturn:
01940
UNLOCK_WS_AND_ADDRESS_SPACE (Process);
01941
01942 ErrorReturn1:
01943
if (Attached) {
01944
KeDetachProcess();
01945 }
01946
if ( ProcessHandle != NtCurrentProcess() ) {
01947
ObDereferenceObject (Process);
01948 }
01949
return Status;
01950 }