Move some profile stuff to NDK and fix some bugs in the executive implementation...
[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 VOID
19 STDCALL
20 PspInheritQuota(PEPROCESS Process, PEPROCESS ParentProcess)
21 {
22 if (ParentProcess != NULL)
23 {
24 PEPROCESS_QUOTA_BLOCK QuotaBlock = ParentProcess->QuotaBlock;
25
26 ASSERT(QuotaBlock != NULL);
27
28 InterlockedIncrementUL(&QuotaBlock->ReferenceCount);
29
30 Process->QuotaBlock = QuotaBlock;
31 }
32 else
33 Process->QuotaBlock = &PspDefaultQuotaBlock;
34 }
35
36 VOID
37 STDCALL
38 PspDestroyQuotaBlock(PEPROCESS Process)
39 {
40 PEPROCESS_QUOTA_BLOCK QuotaBlock = Process->QuotaBlock;
41
42 if (QuotaBlock != &PspDefaultQuotaBlock &&
43 InterlockedDecrementUL(&QuotaBlock->ReferenceCount) == 0)
44 {
45 ExFreePool(QuotaBlock);
46 }
47 }
48
49 /*
50 * @implemented
51 */
52 VOID
53 STDCALL
54 PsChargePoolQuota(IN PEPROCESS Process,
55 IN POOL_TYPE PoolType,
56 IN ULONG Amount)
57 {
58 NTSTATUS Status;
59
60 /* Charge the usage */
61 Status = PsChargeProcessPoolQuota(Process, PoolType, Amount);
62
63 /* Raise Exception */
64 if (!NT_SUCCESS(Status))
65 {
66 ExRaiseStatus(Status);
67 }
68 }
69
70 /*
71 * @implemented
72 */
73 NTSTATUS
74 STDCALL
75 PsChargeProcessNonPagedPoolQuota(IN PEPROCESS Process,
76 IN ULONG_PTR Amount)
77 {
78 /* Call the general function */
79 return PsChargeProcessPoolQuota(Process, NonPagedPool, Amount);
80 }
81
82 /*
83 * @implemented
84 */
85 NTSTATUS
86 STDCALL
87 PsChargeProcessPagedPoolQuota(IN PEPROCESS Process,
88 IN ULONG_PTR Amount)
89 {
90 /* Call the general function */
91 return PsChargeProcessPoolQuota(Process, PagedPool, Amount);
92 }
93
94 /*
95 * @implemented
96 */
97 NTSTATUS
98 STDCALL
99 PsChargeProcessPoolQuota(IN PEPROCESS Process,
100 IN POOL_TYPE PoolType,
101 IN ULONG Amount)
102 {
103 PEPROCESS_QUOTA_BLOCK QuotaBlock;
104 ULONG NewUsageSize;
105 ULONG NewMaxQuota;
106
107 /* Get current Quota Block */
108 QuotaBlock = Process->QuotaBlock;
109
110 /* Quota Operations are not to be done on the SYSTEM Process */
111 if (Process == PsInitialSystemProcess) return STATUS_SUCCESS;
112
113 /* New Size in use */
114 NewUsageSize = QuotaBlock->QuotaEntry[PoolType].Usage + Amount;
115
116 /* Does this size respect the quota? */
117 if (NewUsageSize > QuotaBlock->QuotaEntry[PoolType].Limit)
118 {
119 /* It doesn't, so keep raising the Quota */
120 while (MiRaisePoolQuota(PoolType,
121 QuotaBlock->QuotaEntry[PoolType].Limit,
122 &NewMaxQuota))
123 {
124 /* Save new Maximum Quota */
125 QuotaBlock->QuotaEntry[PoolType].Limit = NewMaxQuota;
126
127 /* See if the new Maximum Quota fulfills our need */
128 if (NewUsageSize <= NewMaxQuota) goto QuotaChanged;
129 }
130
131 return STATUS_QUOTA_EXCEEDED;
132 }
133
134 QuotaChanged:
135 /* Save new Usage */
136 QuotaBlock->QuotaEntry[PoolType].Usage = NewUsageSize;
137
138 /* Is this a new peak? */
139 if (NewUsageSize > QuotaBlock->QuotaEntry[PoolType].Peak)
140 {
141 QuotaBlock->QuotaEntry[PoolType].Peak = NewUsageSize;
142 }
143
144 /* All went well */
145 return STATUS_SUCCESS;
146 }
147
148 /*
149 * @unimplemented
150 */
151 VOID
152 STDCALL
153 PsReturnPoolQuota(IN PEPROCESS Process,
154 IN POOL_TYPE PoolType,
155 IN ULONG_PTR Amount)
156 {
157 UNIMPLEMENTED;
158 }
159
160 /*
161 * @unimplemented
162 */
163 VOID
164 STDCALL
165 PsReturnProcessNonPagedPoolQuota(IN PEPROCESS Process,
166 IN ULONG_PTR Amount)
167 {
168 UNIMPLEMENTED;
169 }
170
171 /*
172 * @unimplemented
173 */
174 VOID
175 STDCALL
176 PsReturnProcessPagedPoolQuota(IN PEPROCESS Process,
177 IN ULONG_PTR Amount)
178 {
179 UNIMPLEMENTED;
180 }
181
182 /* EOF */