00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "psp.h"
00022
00023
PEPROCESS_QUOTA_BLOCK
00024 PsChargeSharedPoolQuota(
00025 IN
PEPROCESS Process,
00026 IN SIZE_T PagedAmount,
00027 IN SIZE_T NonPagedAmount
00028 )
00029
00030
00031
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 KIRQL OldIrql;
00058 SIZE_T NewPoolUsage;
00059
PEPROCESS_QUOTA_BLOCK QuotaBlock;
00060 SIZE_T NewLimit;
00061
00062
ASSERT((Process->Pcb.Header.Type ==
ProcessObject) || (Process->Pcb.Header.Type == 0));
00063
00064 QuotaBlock = Process->QuotaBlock;
00065
00066 retry_charge:
00067
if ( QuotaBlock != &
PspDefaultQuotaBlock ) {
00068 ExAcquireSpinLock(&QuotaBlock->
QuotaLock,&OldIrql);
00069 do_charge:
00070
00071
if ( PagedAmount ) {
00072
00073 NewPoolUsage = QuotaBlock->
QuotaPoolUsage[
PagedPool] + PagedAmount;
00074
00075
00076
00077
00078
00079
00080
if ( NewPoolUsage > QuotaBlock->
QuotaPoolLimit[
PagedPool] ) {
00081
while ( (
PspDefaultPagedLimit == 0) &&
MmRaisePoolQuota(
PagedPool,QuotaBlock->
QuotaPoolLimit[
PagedPool],&NewLimit) ) {
00082 QuotaBlock->
QuotaPoolLimit[
PagedPool] = NewLimit;
00083
if ( NewPoolUsage <= NewLimit ) {
00084
goto LimitRaised0;
00085 }
00086 }
00087
00088 ExReleaseSpinLock(&QuotaBlock->
QuotaLock,OldIrql);
00089
return NULL;
00090 }
00091 LimitRaised0:
00092
if ( NewPoolUsage < QuotaBlock->
QuotaPoolUsage[
PagedPool] ||
00093 NewPoolUsage < PagedAmount ) {
00094
00095 ExReleaseSpinLock(&QuotaBlock->
QuotaLock,OldIrql);
00096
00097
return NULL;
00098 }
00099
00100 QuotaBlock->
QuotaPoolUsage[
PagedPool] = NewPoolUsage;
00101
if ( NewPoolUsage > QuotaBlock->
QuotaPeakPoolUsage[
PagedPool] ) {
00102 QuotaBlock->
QuotaPeakPoolUsage[
PagedPool] = NewPoolUsage;
00103 }
00104 }
00105
00106
if ( NonPagedAmount ) {
00107
00108 NewPoolUsage = QuotaBlock->
QuotaPoolUsage[
NonPagedPool] + NonPagedAmount;
00109
00110
00111
00112
00113
00114
00115
if ( NewPoolUsage > QuotaBlock->
QuotaPoolLimit[
NonPagedPool] ) {
00116
while ( (
PspDefaultNonPagedLimit == 0) &&
MmRaisePoolQuota(
NonPagedPool,QuotaBlock->
QuotaPoolLimit[
NonPagedPool],&NewLimit) ) {
00117 QuotaBlock->
QuotaPoolLimit[
NonPagedPool] = NewLimit;
00118
if ( NewPoolUsage <= NewLimit ) {
00119
goto LimitRaised1;
00120 }
00121 }
00122
if ( PagedAmount ) {
00123 QuotaBlock->
QuotaPoolUsage[
PagedPool] -= PagedAmount;
00124 }
00125 ExReleaseSpinLock(&QuotaBlock->
QuotaLock,OldIrql);
00126
00127
return NULL;
00128 }
00129
00130 LimitRaised1:
00131
if ( NewPoolUsage < QuotaBlock->
QuotaPoolUsage[
NonPagedPool] ||
00132 NewPoolUsage < NonPagedAmount ) {
00133
if ( PagedAmount ) {
00134 QuotaBlock->
QuotaPoolUsage[
PagedPool] -= PagedAmount;
00135 }
00136
00137 ExReleaseSpinLock(&QuotaBlock->
QuotaLock,OldIrql);
00138
00139
return NULL;
00140 }
00141
00142 QuotaBlock->
QuotaPoolUsage[
NonPagedPool] = NewPoolUsage;
00143
if ( NewPoolUsage > QuotaBlock->
QuotaPeakPoolUsage[
NonPagedPool] ) {
00144 QuotaBlock->
QuotaPeakPoolUsage[
NonPagedPool] = NewPoolUsage;
00145 }
00146 }
00147
00148 QuotaBlock->
ReferenceCount++;
00149 ExReleaseSpinLock(&QuotaBlock->
QuotaLock,OldIrql);
00150 }
00151
else {
00152
00153
00154
00155
00156
00157
if ( Process ==
PsInitialSystemProcess ) {
00158
return (
PEPROCESS_QUOTA_BLOCK)1;
00159 }
00160
00161 ExAcquireSpinLock(&
PspDefaultQuotaBlock.
QuotaLock,&OldIrql);
00162
if ( (QuotaBlock = Process->QuotaBlock) != &
PspDefaultQuotaBlock ) {
00163 ExReleaseSpinLock(&
PspDefaultQuotaBlock.
QuotaLock,OldIrql);
00164
goto retry_charge;
00165 }
00166
goto do_charge;
00167
00168 }
00169
return QuotaBlock;
00170
00171 }
00172
00173
VOID
00174 PsReturnSharedPoolQuota(
00175 IN
PEPROCESS_QUOTA_BLOCK QuotaBlock,
00176 IN SIZE_T PagedAmount,
00177 IN SIZE_T NonPagedAmount
00178 )
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 {
00202
00203 KIRQL OldIrql;
00204
00205
00206
00207
00208
00209
if ( QuotaBlock == (
PEPROCESS_QUOTA_BLOCK)1 ) {
00210
return;
00211 }
00212
00213 ExAcquireSpinLock(&QuotaBlock->QuotaLock,&OldIrql);
00214
00215
if ( PagedAmount ) {
00216
00217
if ( PagedAmount <= QuotaBlock->QuotaPoolUsage[
PagedPool] ) {
00218 QuotaBlock->QuotaPoolUsage[
PagedPool] -= PagedAmount;
00219 }
00220
else {
00221
ASSERT(
FALSE);
00222 QuotaBlock->QuotaPoolUsage[
PagedPool] = 0;
00223 }
00224 }
00225
if ( NonPagedAmount ) {
00226
00227
if ( NonPagedAmount <= QuotaBlock->QuotaPoolUsage[
NonPagedPool] ) {
00228 QuotaBlock->QuotaPoolUsage[
NonPagedPool] -= NonPagedAmount;
00229 }
00230
else {
00231
ASSERT(
FALSE);
00232 QuotaBlock->QuotaPoolUsage[
NonPagedPool] = 0;
00233 }
00234 }
00235 QuotaBlock->ReferenceCount--;
00236
if ( QuotaBlock->ReferenceCount == 0 ) {
00237 ExReleaseSpinLock(&QuotaBlock->QuotaLock,OldIrql);
00238
ExFreePool(QuotaBlock);
00239 }
00240
else {
00241 ExReleaseSpinLock(&QuotaBlock->QuotaLock,OldIrql);
00242 }
00243 }
00244
00245
VOID
00246 PsChargePoolQuota(
00247 IN
PEPROCESS Process,
00248 IN POOL_TYPE PoolType,
00249 IN SIZE_T Amount
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 KIRQL OldIrql;
00279 SIZE_T NewPoolUsage;
00280
PEPROCESS_QUOTA_BLOCK QuotaBlock;
00281 SIZE_T NewLimit;
00282 SIZE_T HardLimit;
00283
00284
ASSERT((Process->Pcb.Header.Type ==
ProcessObject) || (Process->Pcb.Header.Type == 0));
00285
00286 QuotaBlock = Process->QuotaBlock;
00287
00288 retry_charge:
00289
if ( QuotaBlock != &
PspDefaultQuotaBlock ) {
00290 ExAcquireSpinLock(&QuotaBlock->
QuotaLock,&OldIrql);
00291 do_charge:
00292 NewPoolUsage = QuotaBlock->
QuotaPoolUsage[PoolType] + Amount;
00293
00294
00295
00296
00297
00298
00299
if ( NewPoolUsage > QuotaBlock->
QuotaPoolLimit[PoolType] ) {
00300
if ( PoolType ==
PagedPool ) {
00301 HardLimit =
PspDefaultPagedLimit;
00302 }
00303
else {
00304 HardLimit =
PspDefaultNonPagedLimit;
00305 }
00306
00307
while ( (HardLimit == 0) &&
MmRaisePoolQuota(PoolType,QuotaBlock->
QuotaPoolLimit[PoolType],&NewLimit) ) {
00308 QuotaBlock->
QuotaPoolLimit[PoolType] = NewLimit;
00309
if ( NewPoolUsage <= NewLimit ) {
00310
goto LimitRaised2;
00311 }
00312 }
00313
00314
00315 ExReleaseSpinLock(&QuotaBlock->
QuotaLock,OldIrql);
00316
ExRaiseStatus(STATUS_QUOTA_EXCEEDED);
00317 }
00318 LimitRaised2:
00319
if ( NewPoolUsage < QuotaBlock->
QuotaPoolUsage[PoolType] ||
00320 NewPoolUsage < Amount ) {
00321
00322 ExReleaseSpinLock(&QuotaBlock->
QuotaLock,OldIrql);
00323
ExRaiseStatus(STATUS_QUOTA_EXCEEDED);
00324 }
00325
00326 QuotaBlock->
QuotaPoolUsage[PoolType] = NewPoolUsage;
00327
if ( NewPoolUsage > QuotaBlock->
QuotaPeakPoolUsage[PoolType] ) {
00328 QuotaBlock->
QuotaPeakPoolUsage[PoolType] = NewPoolUsage;
00329 }
00330
00331 NewPoolUsage = Process->QuotaPoolUsage[PoolType] + Amount;
00332 Process->QuotaPoolUsage[PoolType] = NewPoolUsage;
00333
if ( NewPoolUsage > Process->QuotaPeakPoolUsage[PoolType] ) {
00334 Process->QuotaPeakPoolUsage[PoolType] = NewPoolUsage;
00335 }
00336
00337 ExReleaseSpinLock(&QuotaBlock->
QuotaLock,OldIrql);
00338 }
00339
else {
00340
if ( Process ==
PsInitialSystemProcess ) {
00341
return;
00342 }
00343
00344 ExAcquireSpinLock(&
PspDefaultQuotaBlock.
QuotaLock,&OldIrql);
00345
if ( (QuotaBlock = Process->QuotaBlock) != &
PspDefaultQuotaBlock ) {
00346 ExReleaseSpinLock(&
PspDefaultQuotaBlock.
QuotaLock,OldIrql);
00347
goto retry_charge;
00348 }
00349
goto do_charge;
00350
00351 }
00352
00353 }
00354
00355
VOID
00356 PsReturnPoolQuota(
00357 IN
PEPROCESS Process,
00358 IN POOL_TYPE PoolType,
00359 IN SIZE_T Amount
00360 )
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 {
00385
00386 KIRQL OldIrql;
00387
PEPROCESS_QUOTA_BLOCK QuotaBlock;
00388 SIZE_T GiveBackLimit;
00389 SIZE_T RoundedUsage;
00390
00391
ASSERT((Process->Pcb.Header.Type ==
ProcessObject) || (Process->Pcb.Header.Type == 0));
00392
00393 QuotaBlock = Process->QuotaBlock;
00394 retry_return:
00395
if ( QuotaBlock != &
PspDefaultQuotaBlock) {
00396 ExAcquireSpinLock(&QuotaBlock->
QuotaLock,&OldIrql);
00397
00398
if (
PspDoingGiveBacks ) {
00399
if ( PoolType ==
PagedPool ) {
00400 GiveBackLimit =
MMPAGED_QUOTA_INCREASE;
00401 }
00402
else {
00403 GiveBackLimit =
MMNONPAGED_QUOTA_INCREASE;
00404 }
00405 }
00406
else {
00407 GiveBackLimit = 0;
00408 }
00409 do_return:
00410
if ( Amount <= Process->QuotaPoolUsage[PoolType] ) {
00411 Process->QuotaPoolUsage[PoolType] -= Amount;
00412 }
00413
else {
00414
ASSERT(
FALSE);
00415 GiveBackLimit = 0;
00416 Process->QuotaPoolUsage[PoolType] = 0;
00417 }
00418
00419
if ( Amount <= QuotaBlock->
QuotaPoolUsage[PoolType] ) {
00420 QuotaBlock->
QuotaPoolUsage[PoolType] -= Amount;
00421 }
00422
else {
00423
ASSERT(
FALSE);
00424 GiveBackLimit = 0;
00425 QuotaBlock->
QuotaPoolUsage[PoolType] = 0;
00426 }
00427
00428
if ( GiveBackLimit ) {
00429
if (QuotaBlock->
QuotaPoolLimit[PoolType] - QuotaBlock->
QuotaPoolUsage[PoolType] > GiveBackLimit ) {
00430
00431
00432
00433
00434
00435 RoundedUsage =
ROUND_TO_PAGES(QuotaBlock->
QuotaPoolUsage[PoolType]);
00436
00437
00438
00439
00440
00441 GiveBackLimit = QuotaBlock->
QuotaPoolLimit[PoolType] - RoundedUsage;
00442 QuotaBlock->
QuotaPoolLimit[PoolType] -= GiveBackLimit;
00443
MmReturnPoolQuota(PoolType,GiveBackLimit);
00444
00445 }
00446 }
00447 ExReleaseSpinLock(&QuotaBlock->
QuotaLock,OldIrql);
00448 }
00449
else {
00450
00451
if ( Process ==
PsInitialSystemProcess ) {
00452
return;
00453 }
00454
00455 ExAcquireSpinLock(&
PspDefaultQuotaBlock.
QuotaLock,&OldIrql);
00456
if ( (QuotaBlock = Process->QuotaBlock) != &
PspDefaultQuotaBlock) {
00457 ExReleaseSpinLock(&
PspDefaultQuotaBlock.
QuotaLock,OldIrql);
00458
goto retry_return;
00459 }
00460 GiveBackLimit = 0;
00461
goto do_return;
00462 }
00463 }
00464
00465
VOID
00466 PspInheritQuota(
00467 IN
PEPROCESS NewProcess,
00468 IN
PEPROCESS ParentProcess
00469 )
00470 {
00471
PEPROCESS_QUOTA_BLOCK QuotaBlock;
00472 KIRQL OldIrql;
00473
00474
if ( ParentProcess ) {
00475 QuotaBlock = ParentProcess->QuotaBlock;
00476 }
00477
else {
00478 QuotaBlock = &
PspDefaultQuotaBlock;
00479 }
00480
00481 ExAcquireSpinLock(&QuotaBlock->
QuotaLock,&OldIrql);
00482 QuotaBlock->
ReferenceCount++;
00483 NewProcess->QuotaBlock = QuotaBlock;
00484 ExReleaseSpinLock(&QuotaBlock->
QuotaLock,OldIrql);
00485 }
00486
00487
VOID
00488
MiReturnPageFileQuota (
00489 IN SIZE_T QuotaCharge,
00490 IN
PEPROCESS CurrentProcess
00491 );
00492
00493
VOID
00494 PspDereferenceQuota(
00495 IN
PEPROCESS Process
00496 )
00497 {
00498
PEPROCESS_QUOTA_BLOCK QuotaBlock;
00499 KIRQL OldIrql;
00500
00501 QuotaBlock = Process->QuotaBlock;
00502
00503
PsReturnPoolQuota(Process,
NonPagedPool,Process->QuotaPoolUsage[
NonPagedPool]);
00504
PsReturnPoolQuota(Process,
PagedPool,Process->QuotaPoolUsage[
PagedPool]);
00505
MiReturnPageFileQuota(Process->PagefileUsage,Process);
00506
00507 ExAcquireSpinLock(&QuotaBlock->
QuotaLock,&OldIrql);
00508
00509 QuotaBlock->
ReferenceCount--;
00510
if ( QuotaBlock->
ReferenceCount == 0 ) {
00511 ExReleaseSpinLock(&QuotaBlock->
QuotaLock,OldIrql);
00512
ExFreePool(QuotaBlock);
00513 }
00514
else {
00515 ExReleaseSpinLock(&QuotaBlock->
QuotaLock,OldIrql);
00516 }
00517 }