50a81f046692abe9ccdbb12b657c8a324aca1c4a
[reactos.git] / reactos / ntoskrnl / ps / quota.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ps/quota.c
5 * PURPOSE: Process Pool Quotas
6 *
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
8 */
9
10 /* INCLUDES **************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <internal/debug.h>
15
16 /* FUNCTIONS ***************************************************************/
17
18 /*
19 * @implemented
20 */
21 VOID
22 STDCALL
23 PsChargePoolQuota(IN PEPROCESS Process,
24 IN POOL_TYPE PoolType,
25 IN ULONG_PTR Amount)
26 {
27 NTSTATUS Status;
28
29 /* Charge the usage */
30 Status = PsChargeProcessPoolQuota(Process, PoolType, Amount);
31
32 /* Raise Exception */
33 if (!NT_SUCCESS(Status))
34 {
35 ExRaiseStatus(Status);
36 }
37 }
38
39 /*
40 * @implemented
41 */
42 NTSTATUS
43 STDCALL
44 PsChargeProcessNonPagedPoolQuota(IN PEPROCESS Process,
45 IN ULONG_PTR Amount)
46 {
47 /* Call the general function */
48 return PsChargeProcessPoolQuota(Process, NonPagedPool, Amount);
49 }
50
51 /*
52 * @implemented
53 */
54 NTSTATUS
55 STDCALL
56 PsChargeProcessPagedPoolQuota(IN PEPROCESS Process,
57 IN ULONG_PTR Amount)
58 {
59 /* Call the general function */
60 return PsChargeProcessPoolQuota(Process, PagedPool, Amount);
61 }
62
63 /*
64 * @implemented
65 */
66 NTSTATUS
67 STDCALL
68 PsChargeProcessPoolQuota(IN PEPROCESS Process,
69 IN POOL_TYPE PoolType,
70 IN ULONG_PTR Amount)
71 {
72 PEPROCESS_QUOTA_BLOCK QuotaBlock;
73 ULONG NewUsageSize;
74 ULONG NewMaxQuota;
75
76 /* Get current Quota Block */
77 QuotaBlock = Process->QuotaBlock;
78
79 /* Quota Operations are not to be done on the SYSTEM Process */
80 if (Process == PsInitialSystemProcess) return STATUS_SUCCESS;
81
82 /* New Size in use */
83 NewUsageSize = QuotaBlock->QuotaEntry[PoolType].Usage + Amount;
84
85 /* Does this size respect the quota? */
86 if (NewUsageSize > QuotaBlock->QuotaEntry[PoolType].Limit)
87 {
88 /* It doesn't, so keep raising the Quota */
89 while (MiRaisePoolQuota(PoolType,
90 QuotaBlock->QuotaEntry[PoolType].Limit,
91 &NewMaxQuota))
92 {
93 /* Save new Maximum Quota */
94 QuotaBlock->QuotaEntry[PoolType].Limit = NewMaxQuota;
95
96 /* See if the new Maximum Quota fulfills our need */
97 if (NewUsageSize <= NewMaxQuota) goto QuotaChanged;
98 }
99
100 return STATUS_QUOTA_EXCEEDED;
101 }
102
103 QuotaChanged:
104 /* Save new Usage */
105 QuotaBlock->QuotaEntry[PoolType].Usage = NewUsageSize;
106
107 /* Is this a new peak? */
108 if (NewUsageSize > QuotaBlock->QuotaEntry[PoolType].Peak)
109 {
110 QuotaBlock->QuotaEntry[PoolType].Peak = NewUsageSize;
111 }
112
113 /* All went well */
114 return STATUS_SUCCESS;
115 }
116
117 /*
118 * @unimplemented
119 */
120 VOID
121 STDCALL
122 PsReturnPoolQuota(IN PEPROCESS Process,
123 IN POOL_TYPE PoolType,
124 IN ULONG_PTR Amount)
125 {
126 UNIMPLEMENTED;
127 }
128
129 /*
130 * @unimplemented
131 */
132 VOID
133 STDCALL
134 PsReturnProcessNonPagedPoolQuota(IN PEPROCESS Process,
135 IN ULONG_PTR Amount)
136 {
137 UNIMPLEMENTED;
138 }
139
140 /*
141 * @unimplemented
142 */
143 VOID
144 STDCALL
145 PsReturnProcessPagedPoolQuota(IN PEPROCESS Process,
146 IN ULONG_PTR Amount)
147 {
148 UNIMPLEMENTED;
149 }
150
151 /* EOF */