ReactOS  r76032
quota.c
Go to the documentation of this file.
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  * Mike Nordell
9  */
10 
11 /* INCLUDES **************************************************************/
12 
13 #include <ntoskrnl.h>
14 #include <ntintsafe.h>
15 #define NDEBUG
16 #include <debug.h>
17 
19 static LIST_ENTRY PspQuotaBlockList = {&PspQuotaBlockList, &PspQuotaBlockList};
21 
22 #define TAG_QUOTA_BLOCK 'bQsP'
23 #define VALID_QUOTA_FLAGS (QUOTA_LIMITS_HARDWS_MIN_ENABLE | \
24  QUOTA_LIMITS_HARDWS_MIN_DISABLE | \
25  QUOTA_LIMITS_HARDWS_MAX_ENABLE | \
26  QUOTA_LIMITS_HARDWS_MAX_DISABLE)
27 
28 /* PRIVATE FUNCTIONS *******************************************************/
29 
30 /*
31  * Private helper to charge the specified process quota.
32  * ReturnsSTATUS_QUOTA_EXCEEDED on quota limit check failure.
33  * Updates QuotaPeak as needed for specified PoolIndex.
34  * TODO: Research and possibly add (the undocumented) enum type PS_QUOTA_TYPE
35  * to replace UCHAR for 'PoolIndex'.
36  * Notes: Conceptually translation unit local/private.
37  */
39 NTAPI
41  IN UCHAR PoolIndex,
43 {
44  ASSERT(Process);
45  ASSERT(Process != PsInitialSystemProcess);
46  ASSERT(PoolIndex <= 2);
47  ASSERT(Process->QuotaBlock);
48 
49  /* Note: Race warning. TODO: Needs to add/use lock for this */
50  if (Process->QuotaUsage[PoolIndex] + Amount >
51  Process->QuotaBlock->QuotaEntry[PoolIndex].Limit)
52  {
53  DPRINT1("Quota exceeded, but ROS will let it slide...\n");
54  return STATUS_SUCCESS;
55  //return STATUS_QUOTA_EXCEEDED; /* caller raises the exception */
56  }
57 
58  InterlockedExchangeAdd((LONG*)&Process->QuotaUsage[PoolIndex], Amount);
59 
60  /* Note: Race warning. TODO: Needs to add/use lock for this */
61  if (Process->QuotaPeak[PoolIndex] < Process->QuotaUsage[PoolIndex])
62  {
63  Process->QuotaPeak[PoolIndex] = Process->QuotaUsage[PoolIndex];
64  }
65 
66  return STATUS_SUCCESS;
67 }
68 
69 /*
70  * Private helper to remove quota charge from the specified process quota.
71  * TODO: Research and possibly add (the undocumented) enum type PS_QUOTA_TYPE
72  * to replace UCHAR for 'PoolIndex'.
73  * Notes: Conceptually translation unit local/private.
74  */
75 VOID
76 NTAPI
78  IN UCHAR PoolIndex,
80 {
81  ASSERT(Process);
82  ASSERT(Process != PsInitialSystemProcess);
83  ASSERT(PoolIndex <= 2);
84  ASSERT(!(Amount & 0x80000000)); /* we need to be able to negate it */
85  if (Process->QuotaUsage[PoolIndex] < Amount)
86  {
87  DPRINT1("WARNING: Process->QuotaUsage sanity check failed.\n");
88  }
89  else
90  {
91  InterlockedExchangeAdd((LONG*)&Process->QuotaUsage[PoolIndex],
92  -(LONG)Amount);
93  }
94 }
95 
96 /* FUNCTIONS ***************************************************************/
97 
98 VOID
99 NTAPI
102 {
103  RtlZeroMemory(&PspDefaultQuotaBlock, sizeof(PspDefaultQuotaBlock));
104  PspDefaultQuotaBlock.QuotaEntry[PagedPool].Limit = (SIZE_T)-1;
105  PspDefaultQuotaBlock.QuotaEntry[NonPagedPool].Limit = (SIZE_T)-1;
106  PspDefaultQuotaBlock.QuotaEntry[2].Limit = (SIZE_T)-1; /* Page file */
107  PsGetCurrentProcess()->QuotaBlock = &PspDefaultQuotaBlock;
108 }
109 
110 VOID
111 NTAPI
113 {
114  if (ParentProcess != NULL)
115  {
116  PEPROCESS_QUOTA_BLOCK QuotaBlock = ParentProcess->QuotaBlock;
117 
118  ASSERT(QuotaBlock != NULL);
119 
121 
122  Process->QuotaBlock = QuotaBlock;
123  }
124  else
125  Process->QuotaBlock = &PspDefaultQuotaBlock;
126 }
127 
128 VOID
129 NTAPI
131  PEPROCESS_QUOTA_BLOCK QuotaBlock)
132 {
133  KIRQL OldIrql;
134 
135  KeAcquireSpinLock(&PspQuotaLock, &OldIrql);
136  InsertTailList(&PspQuotaBlockList, &QuotaBlock->QuotaList);
137  KeReleaseSpinLock(&PspQuotaLock, OldIrql);
138 }
139 
140 VOID
141 NTAPI
143 {
144  PEPROCESS_QUOTA_BLOCK QuotaBlock = Process->QuotaBlock;
145  KIRQL OldIrql;
146 
147  if (QuotaBlock != &PspDefaultQuotaBlock &&
148  InterlockedDecrementUL(&QuotaBlock->ReferenceCount) == 0)
149  {
150  KeAcquireSpinLock(&PspQuotaLock, &OldIrql);
151  RemoveEntryList(&QuotaBlock->QuotaList);
152  KeReleaseSpinLock(&PspQuotaLock, OldIrql);
153  ExFreePool(QuotaBlock);
154  }
155 }
156 
157 /*
158  * @implemented
159  */
160 NTSTATUS
161 NTAPI
163  IN SIZE_T Amount)
164 {
165  /* Don't do anything for the system process */
166  if (Process == PsInitialSystemProcess) return STATUS_SUCCESS;
167 
168  return PspChargeProcessQuotaSpecifiedPool(Process, 2, Amount);
169 }
170 
171 /*
172  * @implemented
173  */
174 VOID
175 NTAPI
178  IN SIZE_T Amount)
179 {
182 
183  /* Don't do anything for the system process */
184  if (Process == PsInitialSystemProcess) return;
185 
186  /* Charge the usage */
187  Status = PsChargeProcessPoolQuota(Process, PoolType, Amount);
188  if (!NT_SUCCESS(Status)) ExRaiseStatus(Status);
189 }
190 
191 /*
192  * @implemented
193  */
194 NTSTATUS
195 NTAPI
197  IN SIZE_T Amount)
198 {
199  /* Call the general function */
200  return PsChargeProcessPoolQuota(Process, NonPagedPool, Amount);
201 }
202 
203 /*
204  * @implemented
205  */
206 NTSTATUS
207 NTAPI
209  IN SIZE_T Amount)
210 {
211  /* Call the general function */
212  return PsChargeProcessPoolQuota(Process, PagedPool, Amount);
213 }
214 
215 /*
216  * @implemented
217  */
218 NTSTATUS
219 NTAPI
222  IN SIZE_T Amount)
223 {
224  /* Don't do anything for the system process */
225  if (Process == PsInitialSystemProcess) return STATUS_SUCCESS;
226 
227  return PspChargeProcessQuotaSpecifiedPool(Process,
228  (PoolType & PAGED_POOL_MASK),
229  Amount);
230 }
231 
232 /*
233  * @implemented
234  */
235 VOID
236 NTAPI
239  IN SIZE_T Amount)
240 {
241  /* Don't do anything for the system process */
242  if (Process == PsInitialSystemProcess) return;
243 
245  (PoolType & PAGED_POOL_MASK),
246  Amount);
247 }
248 
249 /*
250  * @implemented
251  */
252 VOID
253 NTAPI
255  IN SIZE_T Amount)
256 {
257  /* Don't do anything for the system process */
258  if (Process == PsInitialSystemProcess) return;
259 
260  PsReturnPoolQuota(Process, NonPagedPool, Amount);
261 }
262 
263 /*
264  * @implemented
265  */
266 VOID
267 NTAPI
269  IN SIZE_T Amount)
270 {
271  /* Don't do anything for the system process */
272  if (Process == PsInitialSystemProcess) return;
273 
274  PsReturnPoolQuota(Process, PagedPool, Amount);
275 }
276 
277 /*
278  * @implemented
279  */
280 NTSTATUS
281 NTAPI
283  IN SIZE_T Amount)
284 {
285  /* Don't do anything for the system process */
286  if (Process == PsInitialSystemProcess) return STATUS_SUCCESS;
287 
288  PspReturnProcessQuotaSpecifiedPool(Process, 2, Amount);
289  return STATUS_SUCCESS;
290 }
291 
292 NTSTATUS
293 NTAPI
296  _In_ ULONG Unused,
297  _In_ PVOID QuotaLimits,
298  _In_ ULONG QuotaLimitsLength,
300 {
301  QUOTA_LIMITS_EX CapturedQuotaLimits;
302  PEPROCESS_QUOTA_BLOCK QuotaBlock, OldQuotaBlock;
303  BOOLEAN IncreaseOkay;
304  KAPC_STATE SavedApcState;
306 
307  UNREFERENCED_PARAMETER(Unused);
308 
309  _SEH2_TRY
310  {
311  ProbeForRead(QuotaLimits, QuotaLimitsLength, sizeof(ULONG));
312 
313  /* Check if we have the basic or extended structure */
314  if (QuotaLimitsLength == sizeof(QUOTA_LIMITS))
315  {
316  /* Copy the basic structure, zero init the remaining fields */
317  RtlCopyMemory(&CapturedQuotaLimits, QuotaLimits, sizeof(QUOTA_LIMITS));
318  CapturedQuotaLimits.WorkingSetLimit = 0;
319  CapturedQuotaLimits.Reserved2 = 0;
320  CapturedQuotaLimits.Reserved3 = 0;
321  CapturedQuotaLimits.Reserved4 = 0;
322  CapturedQuotaLimits.CpuRateLimit.RateData = 0;
323  CapturedQuotaLimits.Flags = 0;
324  }
325  else if (QuotaLimitsLength == sizeof(QUOTA_LIMITS_EX))
326  {
327  /* Copy the full structure */
328  RtlCopyMemory(&CapturedQuotaLimits, QuotaLimits, sizeof(QUOTA_LIMITS_EX));
329 
330  /* Verify that the caller passed valid flags */
331  if ((CapturedQuotaLimits.Flags & ~VALID_QUOTA_FLAGS) ||
332  ((CapturedQuotaLimits.Flags & QUOTA_LIMITS_HARDWS_MIN_ENABLE) &&
333  (CapturedQuotaLimits.Flags & QUOTA_LIMITS_HARDWS_MIN_DISABLE)) ||
334  ((CapturedQuotaLimits.Flags & QUOTA_LIMITS_HARDWS_MAX_ENABLE) &&
335  (CapturedQuotaLimits.Flags & QUOTA_LIMITS_HARDWS_MAX_DISABLE)))
336  {
337  DPRINT1("Invalid quota flags: 0x%lx\n", CapturedQuotaLimits.Flags);
339  }
340 
341  /* Verify that the caller didn't pass reserved values */
342  if ((CapturedQuotaLimits.WorkingSetLimit != 0) ||
343  (CapturedQuotaLimits.Reserved2 != 0) ||
344  (CapturedQuotaLimits.Reserved3 != 0) ||
345  (CapturedQuotaLimits.Reserved4 != 0) ||
346  (CapturedQuotaLimits.CpuRateLimit.RateData != 0))
347  {
348  DPRINT1("Invalid value: (%lx,%lx,%lx,%lx,%lx)\n",
349  CapturedQuotaLimits.WorkingSetLimit,
350  CapturedQuotaLimits.Reserved2,
351  CapturedQuotaLimits.Reserved3,
352  CapturedQuotaLimits.Reserved4,
353  CapturedQuotaLimits.CpuRateLimit.RateData);
355  }
356  }
357  else
358  {
359  DPRINT1("Invalid quota size: 0x%lx\n", QuotaLimitsLength);
361  }
362  }
364  {
365  DPRINT1("Exception while copying data\n");
367  }
368  _SEH2_END;
369 
370  /* Check the caller changes the working set size limits */
371  if ((CapturedQuotaLimits.MinimumWorkingSetSize != 0) &&
372  (CapturedQuotaLimits.MaximumWorkingSetSize != 0))
373  {
374  /* Check for special case: trimming the WS */
375  if ((CapturedQuotaLimits.MinimumWorkingSetSize == SIZE_T_MAX) &&
376  (CapturedQuotaLimits.MaximumWorkingSetSize == SIZE_T_MAX))
377  {
378  /* No increase allowed */
379  IncreaseOkay = FALSE;
380  }
381  else
382  {
383  /* Check if the caller has the required privilege */
385  PreviousMode);
386  }
387 
388  /* Attach to the target process and disable APCs */
389  KeStackAttachProcess(&Process->Pcb, &SavedApcState);
391 
392  /* Call Mm to adjust the process' working set size */
393  Status = MmAdjustWorkingSetSize(CapturedQuotaLimits.MinimumWorkingSetSize,
394  CapturedQuotaLimits.MaximumWorkingSetSize,
395  0,
396  IncreaseOkay);
397 
398  /* Bring back APCs and detach from the process */
400  KeUnstackDetachProcess(&SavedApcState);
401  }
402  else if (Process->QuotaBlock == &PspDefaultQuotaBlock)
403  {
404  /* Check if the caller has the required privilege */
406  {
408  }
409 
410  /* Allocate a new quota block */
411  QuotaBlock = ExAllocatePoolWithTag(NonPagedPool,
412  sizeof(EPROCESS_QUOTA_BLOCK),
414  if (QuotaBlock == NULL)
415  {
416  ObDereferenceObject(Process);
417  return STATUS_NO_MEMORY;
418  }
419 
420  /* Initialize the quota block */
421  QuotaBlock->ReferenceCount = 1;
422  QuotaBlock->ProcessCount = 1;
423  QuotaBlock->QuotaEntry[0].Peak = Process->QuotaPeak[0];
424  QuotaBlock->QuotaEntry[1].Peak = Process->QuotaPeak[1];
425  QuotaBlock->QuotaEntry[2].Peak = Process->QuotaPeak[2];
426  QuotaBlock->QuotaEntry[0].Limit = PspDefaultQuotaBlock.QuotaEntry[0].Limit;
427  QuotaBlock->QuotaEntry[1].Limit = PspDefaultQuotaBlock.QuotaEntry[1].Limit;
428  QuotaBlock->QuotaEntry[2].Limit = PspDefaultQuotaBlock.QuotaEntry[2].Limit;
429 
430  /* Try to exchange the quota block, if that failed, just drop it */
431  OldQuotaBlock = InterlockedCompareExchangePointer((PVOID*)&Process->QuotaBlock,
432  QuotaBlock,
433  &PspDefaultQuotaBlock);
434  if (OldQuotaBlock == &PspDefaultQuotaBlock)
435  {
436  /* Success, insert the new quota block */
437  PspInsertQuotaBlock(QuotaBlock);
438  }
439  else
440  {
441  /* Failed, free the quota block and ignore it */
442  ExFreePoolWithTag(QuotaBlock, TAG_QUOTA_BLOCK);
443  }
444 
445  Status = STATUS_SUCCESS;
446  }
447 
448  return Status;
449 }
450 
451 
452 /* EOF */
DWORD *typedef PVOID
Definition: winlogon.h:52
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define QUOTA_LIMITS_HARDWS_MAX_ENABLE
_Must_inspect_result_ typedef _In_ PVOID Unused
Definition: iotypes.h:1128
#define IN
Definition: typedefs.h:38
_Must_inspect_result_ _In_ LONGLONG _In_ LONGLONG Amount
Definition: fsrtlfuncs.h:550
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define QUOTA_LIMITS_HARDWS_MAX_DISABLE
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
KAPC_STATE
Definition: ketypes.h:1258
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
NTSTATUS NTAPI PsChargeProcessPoolQuota(IN PEPROCESS Process, IN POOL_TYPE PoolType, IN SIZE_T Amount)
Definition: quota.c:220
const LUID SeIncreaseQuotaPrivilege
Definition: priv.c:26
SIZE_T Reserved2
Definition: pstypes.h:75
#define SIZE_T_MAX
Definition: dhcpd.h:91
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:315
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
return STATUS_SUCCESS
Definition: btrfs.c:2664
#define VALID_QUOTA_FLAGS
Definition: quota.c:23
VOID NTAPI PspInsertQuotaBlock(PEPROCESS_QUOTA_BLOCK QuotaBlock)
Definition: quota.c:130
#define ExRaiseStatus
Definition: ntoskrnl.h:94
NTSTATUS NTAPI PsReturnProcessPageFileQuota(IN PEPROCESS Process, IN SIZE_T Amount)
Definition: quota.c:282
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:524
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:267
#define QUOTA_LIMITS_HARDWS_MIN_ENABLE
#define InsertTailList(ListHead, Entry)
NTSTATUS NTAPI MmAdjustWorkingSetSize(IN SIZE_T WorkingSetMinimumInBytes, IN SIZE_T WorkingSetMaximumInBytes, IN ULONG SystemCache, IN BOOLEAN IncreaseOkay)
Definition: mmsup.c:44
#define PAGED_POOL_MASK
Definition: mm.h:96
EPROCESS_QUOTA_ENTRY QuotaEntry[3]
Definition: pstypes.h:978
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock
Definition: quota.c:18
VOID NTAPI PspReturnProcessQuotaSpecifiedPool(IN PEPROCESS Process, IN UCHAR PoolIndex, IN SIZE_T Amount)
Definition: quota.c:77
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:649
long LONG
Definition: pedump.c:60
VOID NTAPI PsChargePoolQuota(IN PEPROCESS Process, IN POOL_TYPE PoolType, IN SIZE_T Amount)
Definition: quota.c:176
NTSTATUS NTAPI PspSetQuotaLimits(_In_ PEPROCESS Process, _In_ ULONG Unused, _In_ PVOID QuotaLimits, _In_ ULONG QuotaLimitsLength, _In_ KPROCESSOR_MODE PreviousMode)
Definition: quota.c:294
#define _SEH2_END
Definition: pseh2_64.h:7
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
VOID NTAPI PsReturnPoolQuota(IN PEPROCESS Process, IN POOL_TYPE PoolType, IN SIZE_T Amount)
Definition: quota.c:237
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:557
#define KeLeaveGuardedRegion()
Definition: ke_x.h:63
#define InterlockedExchangeAdd
Definition: interlocked.h:181
NTSTATUS NTAPI PsChargeProcessPageFileQuota(IN PEPROCESS Process, IN SIZE_T Amount)
Definition: quota.c:162
unsigned char BOOLEAN
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
ULONG RateData
Definition: pstypes.h:60
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
INT POOL_TYPE
Definition: typedefs.h:76
NTSTATUS NTAPI PspChargeProcessQuotaSpecifiedPool(IN PEPROCESS Process, IN UCHAR PoolIndex, IN SIZE_T Amount)
Definition: quota.c:40
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
VOID NTAPI INIT_FUNCTION PsInitializeQuotaSystem(VOID)
Definition: quota.c:101
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define KeEnterGuardedRegion()
Definition: ke_x.h:34
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
PEPROCESS_QUOTA_BLOCK QuotaBlock
Definition: pstypes.h:1238
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
IN REFCLSID IN PUNKNOWN IN POOL_TYPE PoolType
Definition: unknown.h:68
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1452
Definition: typedefs.h:117
NTSTATUS NTAPI PsChargeProcessNonPagedPoolQuota(IN PEPROCESS Process, IN SIZE_T Amount)
Definition: quota.c:196
VOID NTAPI PsReturnProcessNonPagedPoolQuota(IN PEPROCESS Process, IN SIZE_T Amount)
Definition: quota.c:254
Status
Definition: gdiplustypes.h:24
SIZE_T MaximumWorkingSetSize
Definition: pstypes.h:71
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define _In_
Definition: no_sal2.h:204
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define TAG_QUOTA_BLOCK
Definition: quota.c:22
LONG NTSTATUS
Definition: DriverTester.h:11
SIZE_T MinimumWorkingSetSize
Definition: pstypes.h:70
SIZE_T WorkingSetLimit
Definition: pstypes.h:74
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:701
#define InterlockedIncrementUL(Addend)
Definition: ex.h:1455
LIST_ENTRY QuotaList
Definition: pstypes.h:979
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define _SEH2_TRY
Definition: pseh2_64.h:5
SIZE_T Limit
Definition: pstypes.h:971
#define QUOTA_LIMITS_HARDWS_MIN_DISABLE
static LIST_ENTRY PspQuotaBlockList
Definition: quota.c:19
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
RATE_QUOTA_LIMIT CpuRateLimit
Definition: pstypes.h:79
VOID NTAPI PsReturnProcessPagedPoolQuota(IN PEPROCESS Process, IN SIZE_T Amount)
Definition: quota.c:268
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
NTSTATUS NTAPI PsChargeProcessPagedPoolQuota(IN PEPROCESS Process, IN SIZE_T Amount)
Definition: quota.c:208
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1097
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
SIZE_T Reserved3
Definition: pstypes.h:76
VOID NTAPI PspDestroyQuotaBlock(PEPROCESS Process)
Definition: quota.c:142
SIZE_T Peak
Definition: pstypes.h:972
SIZE_T Reserved4
Definition: pstypes.h:77
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
VOID NTAPI PspInheritQuota(PEPROCESS Process, PEPROCESS ParentProcess)
Definition: quota.c:112
#define INIT_FUNCTION
Definition: ntoskrnl.h:11
static KSPIN_LOCK PspQuotaLock
Definition: quota.c:20