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 extern POBJECT_TYPE IoFileObjectType;
00026
00027
NTSTATUS
00028
MiGetWorkingSetInfo (
00029 IN PMEMORY_WORKING_SET_INFORMATION WorkingSetInfo,
00030 IN ULONG Length,
00031 IN
PEPROCESS Process
00032 );
00033
00034
MMPTE
00035
MiCaptureSystemPte (
00036 IN
PMMPTE PointerProtoPte,
00037 IN
PEPROCESS Process
00038 );
00039
00040
#if DBG
00041
PEPROCESS MmWatchProcess;
00042
VOID MmFooBar(VOID);
00043
#endif // DBG
00044
00045 ULONG
00046
MiQueryAddressState (
00047 IN PVOID Va,
00048 IN
PMMVAD Vad,
00049 IN
PEPROCESS TargetProcess,
00050 OUT PULONG ReturnedProtect
00051 );
00052
00053
#ifdef ALLOC_PRAGMA
00054
#pragma alloc_text(PAGE,NtQueryVirtualMemory)
00055
#pragma alloc_text(PAGE,MiQueryAddressState)
00056
#pragma alloc_text(PAGELK,MiGetWorkingSetInfo)
00057
#endif
00058
00059
00060
NTSTATUS
00061 NtQueryVirtualMemory (
00062 IN HANDLE ProcessHandle,
00063 IN PVOID BaseAddress,
00064 IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
00065 OUT PVOID MemoryInformation,
00066 IN ULONG MemoryInformationLength,
00067 OUT PULONG ReturnLength OPTIONAL
00068 )
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 {
00199
KPROCESSOR_MODE PreviousMode;
00200
PEPROCESS TargetProcess;
00201
NTSTATUS Status;
00202
PMMVAD Vad;
00203 BOOLEAN PteIsZero;
00204 PVOID Va;
00205 BOOLEAN Found;
00206 SIZE_T TheRegionSize;
00207 ULONG NewProtect;
00208 ULONG NewState;
00209 PVOID FilePointer;
00210 ULONG_PTR BaseVpn;
00211 MEMORY_BASIC_INFORMATION Info;
00212 LOGICAL Attached;
00213
00214 Found =
FALSE;
00215 PteIsZero =
FALSE;
00216
00217
00218
00219
00220
00221
00222
00223
00224
switch (MemoryInformationClass) {
00225
case MemoryBasicInformation:
00226
if (MemoryInformationLength <
sizeof(MEMORY_BASIC_INFORMATION)) {
00227
return STATUS_INFO_LENGTH_MISMATCH;
00228 }
00229
break;
00230
00231
case MemoryWorkingSetInformation:
00232
if (MemoryInformationLength <
sizeof(ULONG)) {
00233
return STATUS_INFO_LENGTH_MISMATCH;
00234 }
00235
break;
00236
00237
case MemoryMappedFilenameInformation:
00238 FilePointer =
NULL;
00239
break;
00240
default:
00241
return STATUS_INVALID_INFO_CLASS;
00242 }
00243
00244 PreviousMode = KeGetPreviousMode();
00245
00246
if (PreviousMode !=
KernelMode) {
00247
00248
00249
00250
00251
00252
try {
00253
00254
ProbeForWrite(MemoryInformation,
00255 MemoryInformationLength,
00256
sizeof(ULONG_PTR));
00257
00258
if (ARGUMENT_PRESENT(ReturnLength)) {
00259
ProbeForWriteUlong(ReturnLength);
00260 }
00261
00262 } except (
EXCEPTION_EXECUTE_HANDLER) {
00263
00264
00265
00266
00267
00268
00269
00270
return GetExceptionCode();
00271 }
00272 }
00273
if (BaseAddress > MM_HIGHEST_USER_ADDRESS) {
00274
return STATUS_INVALID_PARAMETER;
00275 }
00276
00277
if ((BaseAddress >=
MM_HIGHEST_VAD_ADDRESS)
00278
#if defined(MM_SHARED_USER_DATA_VA)
00279
||
00280 (
PAGE_ALIGN(BaseAddress) == (PVOID)MM_SHARED_USER_DATA_VA)
00281
#endif
00282
) {
00283
00284
00285
00286
00287
00288
if ( MemoryInformationClass == MemoryBasicInformation ) {
00289
00290
try {
00291 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationBase =
00292 (PCHAR)
MM_HIGHEST_VAD_ADDRESS + 1;
00293 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationProtect =
00294 PAGE_READONLY;
00295 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->BaseAddress =
00296
PAGE_ALIGN(BaseAddress);
00297 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->RegionSize =
00298 ((PCHAR)MM_HIGHEST_USER_ADDRESS + 1) -
00299 (PCHAR)
PAGE_ALIGN(BaseAddress);
00300 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->State = MEM_RESERVE;
00301 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Protect = PAGE_NOACCESS;
00302 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Type = MEM_PRIVATE;
00303
00304
if (ARGUMENT_PRESENT(ReturnLength)) {
00305 *ReturnLength =
sizeof(MEMORY_BASIC_INFORMATION);
00306 }
00307
00308
#if defined(MM_SHARED_USER_DATA_VA)
00309
if (
PAGE_ALIGN(BaseAddress) == (PVOID)MM_SHARED_USER_DATA_VA) {
00310
00311
00312
00313
00314
00315
00316 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationBase =
00317 (PVOID)MM_SHARED_USER_DATA_VA;
00318 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Protect =
00319 PAGE_READONLY;
00320 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->RegionSize =
00321
PAGE_SIZE;
00322 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->State =
00323 MEM_COMMIT;
00324 }
00325
#endif
00326
00327 } except (
EXCEPTION_EXECUTE_HANDLER) {
00328
00329
00330
00331
00332 }
00333
00334
return STATUS_SUCCESS;
00335 }
else {
00336
return STATUS_INVALID_ADDRESS;
00337 }
00338 }
00339
00340
if ( ProcessHandle == NtCurrentProcess() ) {
00341 TargetProcess =
PsGetCurrentProcess();
00342 }
else {
00343
Status =
ObReferenceObjectByHandle ( ProcessHandle,
00344 PROCESS_QUERY_INFORMATION,
00345
PsProcessType,
00346 PreviousMode,
00347 (PVOID *)&TargetProcess,
00348
NULL );
00349
00350
if (!
NT_SUCCESS(
Status)) {
00351
return Status;
00352 }
00353 }
00354
00355
if (MemoryInformationClass == MemoryWorkingSetInformation) {
00356
00357
MmLockPagableSectionByHandle(
ExPageLockHandle);
00358
00359
Status =
MiGetWorkingSetInfo (MemoryInformation,
00360 MemoryInformationLength,
00361 TargetProcess);
00362
MmUnlockPagableImageSection(
ExPageLockHandle);
00363
00364
if ( ProcessHandle != NtCurrentProcess() ) {
00365
ObDereferenceObject (TargetProcess);
00366 }
00367
try {
00368
00369
if (ARGUMENT_PRESENT(ReturnLength)) {
00370 *ReturnLength = ((((PMEMORY_WORKING_SET_INFORMATION)
00371 MemoryInformation)->NumberOfEntries - 1) *
00372
sizeof(ULONG)) +
00373
sizeof(MEMORY_WORKING_SET_INFORMATION);
00374 }
00375
00376 } except (
EXCEPTION_EXECUTE_HANDLER) {
00377 }
00378
00379
return STATUS_SUCCESS;
00380 }
00381
00382
00383
00384
00385
00386
00387
if ( ProcessHandle != NtCurrentProcess() ) {
00388
KeAttachProcess (&TargetProcess->
Pcb);
00389 Attached =
TRUE;
00390 }
00391
else {
00392 Attached =
FALSE;
00393 }
00394
00395
00396
00397
00398
00399
LOCK_WS_AND_ADDRESS_SPACE (TargetProcess);
00400
00401
00402
00403
00404
00405
if (TargetProcess->
AddressSpaceDeleted != 0) {
00406
UNLOCK_WS_AND_ADDRESS_SPACE (TargetProcess);
00407
if (Attached ==
TRUE) {
00408
KeDetachProcess();
00409
ObDereferenceObject (TargetProcess);
00410 }
00411
return STATUS_PROCESS_IS_TERMINATING;
00412 }
00413
00414
00415
00416
00417
00418
00419 Vad = TargetProcess->
VadRoot;
00420 BaseVpn =
MI_VA_TO_VPN (BaseAddress);
00421
00422
for (;;) {
00423
00424
if (Vad == (
PMMVAD)
NULL) {
00425
break;
00426 }
00427
00428
if ((BaseVpn >= Vad->
StartingVpn) &&
00429 (BaseVpn <= Vad->
EndingVpn)) {
00430 Found =
TRUE;
00431
break;
00432 }
00433
00434
if (BaseVpn < Vad->
StartingVpn) {
00435
if (Vad->
LeftChild == (
PMMVAD)
NULL) {
00436
break;
00437 }
00438 Vad = Vad->
LeftChild;
00439
00440 }
else {
00441
if (BaseVpn < Vad->
EndingVpn) {
00442
break;
00443 }
00444
if (Vad->
RightChild == (
PMMVAD)
NULL) {
00445
break;
00446 }
00447 Vad = Vad->
RightChild;
00448 }
00449 }
00450
00451
if (!Found) {
00452
00453
00454
00455
00456
00457
00458
00459
if (Vad ==
NULL) {
00460 TheRegionSize = ((PCHAR)
MM_HIGHEST_VAD_ADDRESS + 1) -
00461 (PCHAR)
PAGE_ALIGN(BaseAddress);
00462 }
else {
00463
if (Vad->
StartingVpn < BaseVpn) {
00464
00465
00466
00467
00468
00469
00470 Vad =
MiGetNextVad (Vad);
00471
if (Vad ==
NULL) {
00472 TheRegionSize = ((PCHAR)
MM_HIGHEST_VAD_ADDRESS + 1) -
00473 (PCHAR)
PAGE_ALIGN(BaseAddress);
00474 }
else {
00475 TheRegionSize = (PCHAR)
MI_VPN_TO_VA (Vad->
StartingVpn) -
00476 (PCHAR)
PAGE_ALIGN(BaseAddress);
00477 }
00478 }
else {
00479 TheRegionSize = (PCHAR)
MI_VPN_TO_VA (Vad->
StartingVpn) -
00480 (PCHAR)
PAGE_ALIGN(BaseAddress);
00481 }
00482 }
00483
00484
UNLOCK_WS_AND_ADDRESS_SPACE (TargetProcess);
00485
00486
if (Attached ==
TRUE) {
00487
KeDetachProcess();
00488
ObDereferenceObject (TargetProcess);
00489 }
00490
00491
00492
00493
00494
00495
00496
if ( MemoryInformationClass == MemoryBasicInformation ) {
00497
try {
00498
00499 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationBase =
00500
NULL;
00501 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->AllocationProtect =
00502 0;
00503 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->BaseAddress =
00504
PAGE_ALIGN(BaseAddress);
00505 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->RegionSize =
00506 TheRegionSize;
00507 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->State = MEM_FREE;
00508 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Protect = PAGE_NOACCESS;
00509 ((PMEMORY_BASIC_INFORMATION)MemoryInformation)->Type = 0;
00510
00511
if (ARGUMENT_PRESENT(ReturnLength)) {
00512 *ReturnLength =
sizeof(MEMORY_BASIC_INFORMATION);
00513 }
00514
00515 } except (
EXCEPTION_EXECUTE_HANDLER) {
00516
00517
00518
00519
00520 }
00521
00522
return STATUS_SUCCESS;
00523 }
00524
return STATUS_INVALID_ADDRESS;
00525 }
00526
00527
00528
00529
00530
00531 Va =
PAGE_ALIGN(BaseAddress);
00532 Info.BaseAddress = Va;
00533
00534
00535
00536
00537
00538
if (Vad->
u.VadFlags.PrivateMemory) {
00539 Info.Type = MEM_PRIVATE;
00540 }
else if (Vad->
u.VadFlags.ImageMap == 0) {
00541 Info.Type = MEM_MAPPED;
00542
00543
if ( MemoryInformationClass == MemoryMappedFilenameInformation ) {
00544
if (Vad->
ControlArea) {
00545 FilePointer = Vad->
ControlArea->
FilePointer;
00546 }
00547
if ( !FilePointer ) {
00548 FilePointer = (PVOID)1;
00549 }
else {
00550
ObReferenceObject(FilePointer);
00551 }
00552 }
00553
00554 }
else {
00555 Info.Type = MEM_IMAGE;
00556 }
00557
00558 Info.State =
MiQueryAddressState (Va, Vad, TargetProcess, &Info.Protect);
00559
00560 Va = (PVOID)((PCHAR)Va +
PAGE_SIZE);
00561
00562
while (
MI_VA_TO_VPN (Va) <= Vad->
EndingVpn) {
00563
00564 NewState =
MiQueryAddressState (Va,
00565 Vad,
00566 TargetProcess,
00567 &NewProtect);
00568
00569
if ((NewState != Info.State) || (NewProtect != Info.Protect)) {
00570
00571
00572
00573
00574
00575
00576
break;
00577 }
00578 Va = (PVOID)((PCHAR)Va +
PAGE_SIZE);
00579 }
00580
00581 Info.RegionSize = ((PCHAR)Va - (PCHAR)Info.BaseAddress);
00582 Info.AllocationBase =
MI_VPN_TO_VA (Vad->
StartingVpn);
00583 Info.AllocationProtect =
MI_CONVERT_FROM_PTE_PROTECTION (
00584 Vad->
u.VadFlags.Protection);
00585
00586
00587
00588
00589
00590
00591
#if !(defined(_MIALT4K_))
00592
00593
UNLOCK_WS_AND_ADDRESS_SPACE (TargetProcess);
00594
00595
#else
00596
00597
UNLOCK_WS_UNSAFE (TargetProcess);
00598
00599
if (TargetProcess->
Wow64Process !=
NULL) {
00600
00601 Info.BaseAddress =
PAGE_4K_ALIGN(BaseAddress);
00602
00603
MiQueryRegionFor4kPage(Info.BaseAddress,
00604
MI_VPN_TO_VA_ENDING(Vad->
EndingVpn),
00605 &Info.RegionSize,
00606 &Info.State,
00607 &Info.Protect,
00608 TargetProcess);
00609 }
00610
00611
UNLOCK_ADDRESS_SPACE (TargetProcess);
00612
00613
#endif
00614
00615
if (Attached ==
TRUE) {
00616
KeDetachProcess();
00617
ObDereferenceObject (TargetProcess);
00618 }
00619
00620
#if DBG
00621
if (MmDebug &
MM_DBG_SHOW_NT_CALLS) {
00622
if ( !MmWatchProcess ) {
00623
DbgPrint(
"queryvm base %lx allocbase %lx protect %lx size %lx\n",
00624 Info.BaseAddress, Info.AllocationBase, Info.AllocationProtect,
00625 Info.RegionSize);
00626
DbgPrint(
" state %lx protect %lx type %lx\n",
00627 Info.State, Info.Protect, Info.Type);
00628 }
00629 }
00630
#endif //DBG
00631
00632
if ( MemoryInformationClass == MemoryBasicInformation ) {
00633
try {
00634
00635 *(PMEMORY_BASIC_INFORMATION)MemoryInformation = Info;
00636
00637
if (ARGUMENT_PRESENT(ReturnLength)) {
00638 *ReturnLength =
sizeof(MEMORY_BASIC_INFORMATION);
00639 }
00640
00641 } except (
EXCEPTION_EXECUTE_HANDLER) {
00642 }
00643
return STATUS_SUCCESS;
00644 }
00645
00646
00647
00648
00649
00650
if ( !FilePointer ) {
00651
return STATUS_INVALID_ADDRESS;
00652 }
else if ( FilePointer == (PVOID)1 ) {
00653
return STATUS_FILE_INVALID;
00654 }
00655
00656
00657
00658
00659
00660
00661
Status =
ObQueryNameString(
00662 FilePointer,
00663 MemoryInformation,
00664 MemoryInformationLength,
00665 ReturnLength
00666 );
00667
ObDereferenceObject(FilePointer);
00668
return Status;
00669 }
00670
00671
00672 ULONG
00673 MiQueryAddressState (
00674 IN PVOID Va,
00675 IN
PMMVAD Vad,
00676 IN
PEPROCESS TargetProcess,
00677 OUT PULONG ReturnedProtect
00678 )
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697 {
00698
PMMPTE PointerPte;
00699
PMMPTE PointerPde;
00700
PMMPTE PointerPpe;
00701
MMPTE CapturedProtoPte;
00702
PMMPTE ProtoPte;
00703 ULONG PteIsZero;
00704 ULONG State;
00705 ULONG Protect;
00706 ULONG Waited;
00707 LOGICAL PteDetected;
00708
00709
#ifdef LARGE_PAGES
00710
if (Vad->u.VadFlags.LargePages) {
00711 *ReturnedProtect =
MI_CONVERT_FROM_PTE_PROTECTION (
00712 Vad->u.VadFlags.Protection);
00713
return MEM_COMMIT;
00714 }
00715
#endif //LARGE_PAGES
00716
00717 PointerPpe =
MiGetPpeAddress (Va);
00718 PointerPde =
MiGetPdeAddress (Va);
00719 PointerPte =
MiGetPteAddress (Va);
00720
00721
ASSERT ((Vad->StartingVpn <=
MI_VA_TO_VPN (Va)) &&
00722 (Vad->EndingVpn >=
MI_VA_TO_VPN (Va)));
00723
00724 PteIsZero =
TRUE;
00725 PteDetected =
FALSE;
00726
00727
do {
00728
00729
if (!
MiDoesPpeExistAndMakeValid(PointerPpe,
00730 TargetProcess,
00731
FALSE,
00732 &Waited)) {
00733
break;
00734 }
00735
00736 Waited = 0;
00737
00738
if (!
MiDoesPdeExistAndMakeValid(PointerPde,
00739 TargetProcess,
00740
FALSE,
00741 &Waited)) {
00742
break;
00743 }
00744
00745
if (Waited == 0) {
00746 PteDetected =
TRUE;
00747 }
00748
00749 }
while (Waited != 0);
00750
00751
if (PteDetected ==
TRUE) {
00752
00753
00754
00755
00756
00757
if (PointerPte->
u.Long != 0) {
00758
00759 PteIsZero =
FALSE;
00760
00761
00762
00763
00764
00765
00766
if (
MiIsPteDecommittedPage (PointerPte)) {
00767 Protect = 0;
00768 State = MEM_RESERVE;
00769 }
else {
00770
00771 State = MEM_COMMIT;
00772
if (Vad->u.VadFlags.PhysicalMapping == 1) {
00773
00774
00775
00776
00777
00778
00779 Protect =
MI_CONVERT_FROM_PTE_PROTECTION (
00780 Vad->u.VadFlags.Protection);
00781 }
else {
00782 Protect =
MiGetPageProtection (PointerPte,
00783 TargetProcess);
00784
00785
if ((PointerPte->
u.Soft.Valid == 0) &&
00786 (PointerPte->
u.Soft.Prototype == 1) &&
00787 (Vad->u.VadFlags.PrivateMemory == 0) &&
00788 (Vad->ControlArea != (
PCONTROL_AREA)
NULL)) {
00789
00790
00791
00792
00793
00794 ProtoPte =
MiGetProtoPteAddress(Vad,
00795
MI_VA_TO_VPN (Va));
00796 CapturedProtoPte.
u.Long = 0;
00797
if (ProtoPte) {
00798 CapturedProtoPte =
MiCaptureSystemPte (ProtoPte,
00799 TargetProcess);
00800 }
00801
if (CapturedProtoPte.
u.Long == 0) {
00802 State = MEM_RESERVE;
00803 Protect = 0;
00804 }
00805 }
00806 }
00807 }
00808 }
00809 }
00810
00811
if (PteIsZero) {
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 State = MEM_RESERVE;
00825 Protect = 0;
00826
00827
if (Vad->u.VadFlags.PhysicalMapping == 1) {
00828
00829
00830
00831
00832
00833 NOTHING;
00834
00835 }
else if ((Vad->u.VadFlags.PrivateMemory == 0) &&
00836 (Vad->ControlArea != (
PCONTROL_AREA)
NULL)) {
00837
00838
00839
00840
00841
00842
00843 ProtoPte =
MiGetProtoPteAddress(Vad,
MI_VA_TO_VPN (Va));
00844
00845 CapturedProtoPte.
u.Long = 0;
00846
if (ProtoPte) {
00847 CapturedProtoPte =
MiCaptureSystemPte (ProtoPte,
00848 TargetProcess);
00849 }
00850
00851
if (CapturedProtoPte.
u.Long != 0) {
00852 State = MEM_COMMIT;
00853
00854
if (Vad->u.VadFlags.ImageMap == 0) {
00855 Protect =
MI_CONVERT_FROM_PTE_PROTECTION (
00856 Vad->u.VadFlags.Protection);
00857 }
else {
00858
00859
00860
00861
00862
00863
00864 Protect =
MiGetPageProtection (&CapturedProtoPte,
00865 TargetProcess);
00866 }
00867 }
00868
00869 }
else {
00870
00871
00872
00873
00874
00875
if (Vad->u.VadFlags.MemCommit) {
00876 State = MEM_COMMIT;
00877 Protect =
MI_CONVERT_FROM_PTE_PROTECTION (
00878 Vad->u.VadFlags.Protection);
00879 }
00880 }
00881 }
00882
00883 *ReturnedProtect = Protect;
00884
return State;
00885 }
00886
00887
00888
00889
NTSTATUS
00890 MiGetWorkingSetInfo (
00891 IN PMEMORY_WORKING_SET_INFORMATION WorkingSetInfo,
00892 IN ULONG Length,
00893 IN
PEPROCESS Process
00894 )
00895
00896 {
00897
PMDL Mdl;
00898 PMEMORY_WORKING_SET_INFORMATION Info;
00899 PMEMORY_WORKING_SET_BLOCK Entry;
00900 PMEMORY_WORKING_SET_BLOCK LastEntry;
00901
PMMWSLE Wsle;
00902
PMMWSLE LastWsle;
00903 ULONG WsSize;
00904
PMMPTE PointerPte;
00905
PMMPFN Pfn1;
00906
NTSTATUS status;
00907 LOGICAL Attached;
00908
00909
00910
00911
00912
00913 Mdl =
ExAllocatePoolWithTag (
NonPagedPool,
00914
sizeof(
MDL) +
sizeof(PFN_NUMBER) +
00915
BYTES_TO_PAGES (Length) *
sizeof(PFN_NUMBER),
00916 ' mM');
00917
00918
if (Mdl ==
NULL) {
00919
return(STATUS_INSUFFICIENT_RESOURCES);
00920 }
00921
00922
00923
00924
00925
00926
MmInitializeMdl(Mdl, WorkingSetInfo, Length);
00927
00928
try {
00929
MmProbeAndLockPages (Mdl, KeGetPreviousMode(),
IoWriteAccess);
00930 } except (
EXCEPTION_EXECUTE_HANDLER) {
00931
ExFreePool (Mdl);
00932
return GetExceptionCode();
00933 }
00934
00935 Info =
MmGetSystemAddressForMdlSafe (Mdl,
NormalPagePriority);
00936
00937
if (Info ==
NULL) {
00938
MmUnlockPages (Mdl);
00939
ExFreePool (Mdl);
00940
return STATUS_INSUFFICIENT_RESOURCES;
00941 }
00942
00943
if (
PsGetCurrentProcess() != Process) {
00944
KeAttachProcess (&Process->Pcb);
00945 Attached =
TRUE;
00946 }
00947
else {
00948 Attached =
FALSE;
00949 }
00950
00951
LOCK_WS (Process);
00952
00953 status = STATUS_SUCCESS;
00954
00955
if (Process->AddressSpaceDeleted != 0) {
00956 status = STATUS_PROCESS_IS_TERMINATING;
00957 }
00958
00959 WsSize = Process->Vm.WorkingSetSize;
00960 Info->NumberOfEntries = WsSize;
00961
00962
if ((WsSize *
sizeof(ULONG)) >= Length) {
00963 status = STATUS_INFO_LENGTH_MISMATCH;
00964 }
00965
00966
if (status != STATUS_SUCCESS) {
00967
UNLOCK_WS (Process);
00968
if (Attached ==
TRUE) {
00969
KeDetachProcess ();
00970 }
00971
MmUnlockPages (Mdl);
00972
ExFreePool (Mdl);
00973
return status;
00974 }
00975
00976 Wsle =
MmWsle;
00977 LastWsle = &
MmWsle[
MmWorkingSetList->
LastEntry];
00978 Entry = &Info->WorkingSetInfo[0];
00979 LastEntry = (PMEMORY_WORKING_SET_BLOCK)(
00980 (PCHAR)Info + (Length & (~(
sizeof(ULONG) - 1))));
00981
00982
do {
00983
if (Wsle->
u1.e1.Valid == 1) {
00984 Entry->VirtualPage = Wsle->
u1.e1.VirtualPageNumber;
00985 PointerPte =
MiGetPteAddress (Wsle->
u1.VirtualAddress);
00986
ASSERT (PointerPte->
u.Hard.Valid == 1);
00987 Pfn1 =
MI_PFN_ELEMENT (PointerPte->
u.Hard.PageFrameNumber);
00988
00989 Entry->Shared = Pfn1->
u3.e1.PrototypePte;
00990
if (Pfn1->
u3.e1.PrototypePte == 0) {
00991 Entry->ShareCount = 0;
00992 Entry->Protection =
MI_GET_PROTECTION_FROM_SOFT_PTE(&Pfn1->
OriginalPte);
00993 }
else {
00994
if (Pfn1->
u2.ShareCount <= 7) {
00995 Entry->ShareCount = Pfn1->
u2.ShareCount;
00996 }
00997
else {
00998 Entry->ShareCount = 7;
00999 }
01000
if (Wsle->
u1.e1.SameProtectAsProto == 1) {
01001 Entry->Protection =
MI_GET_PROTECTION_FROM_SOFT_PTE(&Pfn1->
OriginalPte);
01002 }
else {
01003 Entry->Protection = Wsle->
u1.e1.Protection;
01004 }
01005 }
01006 Entry += 1;
01007 }
01008 Wsle += 1;
01009 }
while ((Entry < LastEntry) && (Wsle <= LastWsle));
01010
01011
UNLOCK_WS (Process);
01012
if (Attached ==
TRUE) {
01013
KeDetachProcess ();
01014 }
01015
MmUnlockPages (Mdl);
01016
ExFreePool (Mdl);
01017
return STATUS_SUCCESS;
01018 }