2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ps/quota.c
5 * PURPOSE: Process Pool Quotas
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
10 /* INCLUDES **************************************************************/
14 #include <internal/debug.h>
16 EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock
;
18 /* FUNCTIONS ***************************************************************/
22 PsInitializeQuotaSystem(VOID
)
24 RtlZeroMemory(&PspDefaultQuotaBlock
, sizeof(PspDefaultQuotaBlock
));
25 PspDefaultQuotaBlock
.QuotaEntry
[PagedPool
].Limit
= (SIZE_T
)-1;
26 PspDefaultQuotaBlock
.QuotaEntry
[NonPagedPool
].Limit
= (SIZE_T
)-1;
27 PspDefaultQuotaBlock
.QuotaEntry
[2].Limit
= (SIZE_T
)-1; /* Page file */
28 PsGetCurrentProcess()->QuotaBlock
= &PspDefaultQuotaBlock
;
33 PspInheritQuota(PEPROCESS Process
, PEPROCESS ParentProcess
)
35 if (ParentProcess
!= NULL
)
37 PEPROCESS_QUOTA_BLOCK QuotaBlock
= ParentProcess
->QuotaBlock
;
39 ASSERT(QuotaBlock
!= NULL
);
41 (void)InterlockedIncrementUL(&QuotaBlock
->ReferenceCount
);
43 Process
->QuotaBlock
= QuotaBlock
;
46 Process
->QuotaBlock
= &PspDefaultQuotaBlock
;
51 PspDestroyQuotaBlock(PEPROCESS Process
)
53 PEPROCESS_QUOTA_BLOCK QuotaBlock
= Process
->QuotaBlock
;
55 if (QuotaBlock
!= &PspDefaultQuotaBlock
&&
56 InterlockedDecrementUL(&QuotaBlock
->ReferenceCount
) == 0)
58 ExFreePool(QuotaBlock
);
67 PsChargePoolQuota(IN PEPROCESS Process
,
68 IN POOL_TYPE PoolType
,
73 /* Charge the usage */
74 Status
= PsChargeProcessPoolQuota(Process
, PoolType
, Amount
);
77 if (!NT_SUCCESS(Status
))
79 ExRaiseStatus(Status
);
88 PsChargeProcessNonPagedPoolQuota(IN PEPROCESS Process
,
91 /* Call the general function */
92 return PsChargeProcessPoolQuota(Process
, NonPagedPool
, Amount
);
100 PsChargeProcessPagedPoolQuota(IN PEPROCESS Process
,
103 /* Call the general function */
104 return PsChargeProcessPoolQuota(Process
, PagedPool
, Amount
);
112 PsChargeProcessPoolQuota(IN PEPROCESS Process
,
113 IN POOL_TYPE PoolType
,
116 PEPROCESS_QUOTA_BLOCK QuotaBlock
;
120 /* Get current Quota Block */
121 QuotaBlock
= Process
->QuotaBlock
;
123 /* Quota Operations are not to be done on the SYSTEM Process */
124 if (Process
== PsInitialSystemProcess
) return STATUS_SUCCESS
;
126 /* New Size in use */
127 NewUsageSize
= QuotaBlock
->QuotaEntry
[PoolType
].Usage
+ Amount
;
129 /* Does this size respect the quota? */
130 if (NewUsageSize
> QuotaBlock
->QuotaEntry
[PoolType
].Limit
)
132 /* It doesn't, so keep raising the Quota */
133 while (MiRaisePoolQuota(PoolType
,
134 QuotaBlock
->QuotaEntry
[PoolType
].Limit
,
137 /* Save new Maximum Quota */
138 QuotaBlock
->QuotaEntry
[PoolType
].Limit
= NewMaxQuota
;
140 /* See if the new Maximum Quota fulfills our need */
141 if (NewUsageSize
<= NewMaxQuota
) goto QuotaChanged
;
144 return STATUS_QUOTA_EXCEEDED
;
149 QuotaBlock
->QuotaEntry
[PoolType
].Usage
= NewUsageSize
;
151 /* Is this a new peak? */
152 if (NewUsageSize
> QuotaBlock
->QuotaEntry
[PoolType
].Peak
)
154 QuotaBlock
->QuotaEntry
[PoolType
].Peak
= NewUsageSize
;
158 return STATUS_SUCCESS
;
166 PsReturnPoolQuota(IN PEPROCESS Process
,
167 IN POOL_TYPE PoolType
,
178 PsReturnProcessNonPagedPoolQuota(IN PEPROCESS Process
,
189 PsReturnProcessPagedPoolQuota(IN PEPROCESS Process
,