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
MmFrontOfList;
00026
00027
00028
VOID
00029
FASTCALL
00030 MiDecrementShareCount (
00031 IN PFN_NUMBER PageFrameIndex
00032 )
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 {
00060
MMPTE TempPte;
00061
PMMPTE PointerPte;
00062
PMMPFN Pfn1;
00063 KIRQL OldIrql;
00064
00065
ASSERT ((PageFrameIndex <=
MmHighestPhysicalPage) &&
00066 (PageFrameIndex > 0));
00067
00068 Pfn1 =
MI_PFN_ELEMENT (PageFrameIndex);
00069
00070
if (Pfn1->
u3.e1.PageLocation !=
ActiveAndValid &&
00071 Pfn1->
u3.e1.PageLocation !=
StandbyPageList) {
00072
KeBugCheckEx (PFN_LIST_CORRUPT,
00073 0x99,
00074 PageFrameIndex,
00075 Pfn1->
u3.e1.PageLocation,
00076 0);
00077 }
00078
00079
#if PFN_CONSISTENCY
00080
if (Pfn1->
u3.e1.PageTablePage == 1) {
00081
00082
00083
00084
00085
00086
00087 }
00088
#endif
00089
00090 Pfn1->
u2.ShareCount -= 1;
00091
00092
PERFINFO_DECREFCNT(Pfn1, PERFINFO_LOG_WSCHANGE, PERFINFO_LOG_TYPE_DECSHARCNT)
00093
00094
ASSERT (Pfn1->
u2.ShareCount < 0xF000000);
00095
00096
if (Pfn1->
u2.ShareCount == 0) {
00097
00098
PERFINFO_DECREFCNT(Pfn1, PERFINFO_LOG_EMPTYQ, PERFINFO_LOG_TYPE_ZEROSHARECOUNT)
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
if (Pfn1->
u3.e1.PrototypePte == 1) {
00116
00117 OldIrql = 99;
00118
if (
MmIsAddressValid (Pfn1->
PteAddress)) {
00119 PointerPte = Pfn1->
PteAddress;
00120 }
else {
00121
00122
00123
00124
00125
00126
00127 PointerPte = (
PMMPTE)
MiMapPageInHyperSpace(Pfn1->
PteFrame,
00128 &OldIrql);
00129 PointerPte = (
PMMPTE)((PCHAR)PointerPte +
00130
MiGetByteOffset(Pfn1->
PteAddress));
00131 }
00132
00133 TempPte = *PointerPte;
00134
MI_MAKE_VALID_PTE_TRANSITION (TempPte,
00135 Pfn1->
OriginalPte.
u.Soft.Protection);
00136
MI_WRITE_INVALID_PTE (PointerPte, TempPte);
00137
00138
if (OldIrql != 99) {
00139
MiUnmapPageInHyperSpace (OldIrql);
00140 }
00141
00142
00143
00144
00145
00146
00147 }
00148
00149
00150
00151
00152
00153 Pfn1->
u3.e1.PageLocation =
TransitionPage;
00154
00155
00156
00157
00158
00159
MiDecrementReferenceCount (PageFrameIndex);
00160 }
00161
00162
return;
00163 }
00164
00165
VOID
00166
FASTCALL
00167 MiDecrementReferenceCount (
00168 IN PFN_NUMBER PageFrameIndex
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
PMMPFN Pfn1;
00200
00201
MM_PFN_LOCK_ASSERT();
00202
00203
ASSERT (PageFrameIndex <=
MmHighestPhysicalPage);
00204
00205 Pfn1 =
MI_PFN_ELEMENT (PageFrameIndex);
00206
ASSERT (Pfn1->
u3.e2.ReferenceCount != 0);
00207 Pfn1->
u3.e2.ReferenceCount -= 1;
00208
00209
00210
if (Pfn1->
u3.e2.ReferenceCount != 0) {
00211
00212
00213
00214
00215
00216
return;
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
if (Pfn1->
u2.ShareCount != 0) {
00226
00227
KeBugCheckEx (PFN_LIST_CORRUPT,
00228 7,
00229 PageFrameIndex,
00230 Pfn1->
u2.ShareCount,
00231 0);
00232
return;
00233 }
00234
00235
ASSERT (Pfn1->
u3.e1.PageLocation !=
ActiveAndValid);
00236
00237
if (
MI_IS_PFN_DELETED (Pfn1)) {
00238
00239
00240
00241
00242
00243
00244
MiReleasePageFileSpace (Pfn1->
OriginalPte);
00245
00246
if (Pfn1->
u3.e1.RemovalRequested == 1) {
00247
MiInsertPageInList (
MmPageLocationList[
BadPageList],
00248 PageFrameIndex);
00249 }
00250
else {
00251
MiInsertPageInList (
MmPageLocationList[
FreePageList],
00252 PageFrameIndex);
00253 }
00254
00255
return;
00256 }
00257
00258
00259
00260
00261
00262
00263
if (Pfn1->
u3.e1.Modified == 1) {
00264
MiInsertPageInList (
MmPageLocationList[
ModifiedPageList], PageFrameIndex);
00265 }
else {
00266
00267
if (Pfn1->
u3.e1.RemovalRequested == 1) {
00268
00269
00270
00271
00272
00273
00274
00275
00276 Pfn1->
u3.e1.PageLocation =
StandbyPageList;
00277
00278
MiRestoreTransitionPte (PageFrameIndex);
00279
MiInsertPageInList (
MmPageLocationList[
BadPageList],
00280 PageFrameIndex);
00281
return;
00282 }
00283
00284
if (!
MmFrontOfList) {
00285
MiInsertPageInList (
MmPageLocationList[
StandbyPageList],
00286 PageFrameIndex);
00287 }
else {
00288
MiInsertStandbyListAtFront (PageFrameIndex);
00289 }
00290 }
00291
00292
return;
00293 }