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 /* FUNCTIONS ***************************************************************/
20 PspInheritQuota(PEPROCESS Process
, PEPROCESS ParentProcess
)
22 if (ParentProcess
!= NULL
)
24 PEPROCESS_QUOTA_BLOCK QuotaBlock
= ParentProcess
->QuotaBlock
;
26 ASSERT(QuotaBlock
!= NULL
);
28 InterlockedIncrementUL(&QuotaBlock
->ReferenceCount
);
30 Process
->QuotaBlock
= QuotaBlock
;
33 Process
->QuotaBlock
= &PspDefaultQuotaBlock
;
38 PspDestroyQuotaBlock(PEPROCESS Process
)
40 PEPROCESS_QUOTA_BLOCK QuotaBlock
= Process
->QuotaBlock
;
42 if (QuotaBlock
!= &PspDefaultQuotaBlock
&&
43 InterlockedDecrementUL(&QuotaBlock
->ReferenceCount
) == 0)
45 ExFreePool(QuotaBlock
);
54 PsChargePoolQuota(IN PEPROCESS Process
,
55 IN POOL_TYPE PoolType
,
60 /* Charge the usage */
61 Status
= PsChargeProcessPoolQuota(Process
, PoolType
, Amount
);
64 if (!NT_SUCCESS(Status
))
66 ExRaiseStatus(Status
);
75 PsChargeProcessNonPagedPoolQuota(IN PEPROCESS Process
,
78 /* Call the general function */
79 return PsChargeProcessPoolQuota(Process
, NonPagedPool
, Amount
);
87 PsChargeProcessPagedPoolQuota(IN PEPROCESS Process
,
90 /* Call the general function */
91 return PsChargeProcessPoolQuota(Process
, PagedPool
, Amount
);
99 PsChargeProcessPoolQuota(IN PEPROCESS Process
,
100 IN POOL_TYPE PoolType
,
103 PEPROCESS_QUOTA_BLOCK QuotaBlock
;
107 /* Get current Quota Block */
108 QuotaBlock
= Process
->QuotaBlock
;
110 /* Quota Operations are not to be done on the SYSTEM Process */
111 if (Process
== PsInitialSystemProcess
) return STATUS_SUCCESS
;
113 /* New Size in use */
114 NewUsageSize
= QuotaBlock
->QuotaEntry
[PoolType
].Usage
+ Amount
;
116 /* Does this size respect the quota? */
117 if (NewUsageSize
> QuotaBlock
->QuotaEntry
[PoolType
].Limit
)
119 /* It doesn't, so keep raising the Quota */
120 while (MiRaisePoolQuota(PoolType
,
121 QuotaBlock
->QuotaEntry
[PoolType
].Limit
,
124 /* Save new Maximum Quota */
125 QuotaBlock
->QuotaEntry
[PoolType
].Limit
= NewMaxQuota
;
127 /* See if the new Maximum Quota fulfills our need */
128 if (NewUsageSize
<= NewMaxQuota
) goto QuotaChanged
;
131 return STATUS_QUOTA_EXCEEDED
;
136 QuotaBlock
->QuotaEntry
[PoolType
].Usage
= NewUsageSize
;
138 /* Is this a new peak? */
139 if (NewUsageSize
> QuotaBlock
->QuotaEntry
[PoolType
].Peak
)
141 QuotaBlock
->QuotaEntry
[PoolType
].Peak
= NewUsageSize
;
145 return STATUS_SUCCESS
;
153 PsReturnPoolQuota(IN PEPROCESS Process
,
154 IN POOL_TYPE PoolType
,
165 PsReturnProcessNonPagedPoolQuota(IN PEPROCESS Process
,
176 PsReturnProcessPagedPoolQuota(IN PEPROCESS Process
,