ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

quota.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS kernel
00004  * FILE:            ntoskrnl/ps/quota.c
00005  * PURPOSE:         Process Pool Quotas
00006  *
00007  * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
00008  *                  Mike Nordell
00009  */
00010 
00011 /* INCLUDES **************************************************************/
00012 
00013 #include <ntoskrnl.h>
00014 #define NDEBUG
00015 #include <debug.h>
00016 
00017 EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock;
00018 
00019 
00020 /* Define this macro to enable quota code testing. Once quota code is */
00021 /* stable and verified, remove this macro and checks for it. */
00022 /*#define PS_QUOTA_ENABLE_QUOTA_CODE*/
00023 
00024 
00025 /* PRIVATE FUNCTIONS *******************************************************/
00026 
00027 #ifdef PS_QUOTA_ENABLE_QUOTA_CODE
00028 
00029 /*
00030  * Private helper to charge the specified process quota.
00031  * ReturnsSTATUS_QUOTA_EXCEEDED on quota limit check failure.
00032  * Updates QuotaPeak as needed for specified PoolIndex.
00033  * TODO: Research and possibly add (the undocumented) enum type PS_QUOTA_TYPE
00034  *       to replace UCHAR for 'PoolIndex'.
00035  * Notes: Conceptually translation unit local/private.
00036  */
00037 NTSTATUS
00038 NTAPI
00039 PspChargeProcessQuotaSpecifiedPool(IN PEPROCESS Process,
00040                                    IN UCHAR     PoolIndex,
00041                                    IN SIZE_T    Amount)
00042 {
00043     ASSERT(Process);
00044     ASSERT(Process != PsInitialSystemProcess);
00045     ASSERT(PoolIndex <= 2);
00046     ASSERT(Process->QuotaBlock);
00047 
00048     /* Note: Race warning. TODO: Needs to add/use lock for this */
00049     if (Process->QuotaUsage[PoolIndex] + Amount >
00050         Process->QuotaBlock->QuotaEntry[PoolIndex].Limit)
00051     {
00052         return STATUS_QUOTA_EXCEEDED; /* caller raises the exception */
00053     }
00054 
00055     InterlockedExchangeAdd((LONG*)&Process->QuotaUsage[PoolIndex], Amount);
00056 
00057     /* Note: Race warning. TODO: Needs to add/use lock for this */
00058     if (Process->QuotaPeak[PoolIndex] < Process->QuotaUsage[PoolIndex])
00059     {
00060         Process->QuotaPeak[PoolIndex] = Process->QuotaUsage[PoolIndex];
00061     }
00062 
00063     return STATUS_SUCCESS;
00064 }
00065 
00066 
00067 /*
00068  * Private helper to remove quota charge from the specified process quota.
00069  * TODO: Research and possibly add (the undocumented) enum type PS_QUOTA_TYPE
00070  *       to replace UCHAR for 'PoolIndex'.
00071  * Notes: Conceptually translation unit local/private.
00072  */
00073 VOID
00074 NTAPI
00075 PspReturnProcessQuotaSpecifiedPool(IN PEPROCESS Process,
00076                                    IN UCHAR     PoolIndex,
00077                                    IN SIZE_T    Amount)
00078 {
00079     ASSERT(Process);
00080     ASSERT(Process != PsInitialSystemProcess);
00081     ASSERT(PoolIndex <= 2);
00082     ASSERT(!(Amount & 0x80000000)); /* we need to be able to negate it */
00083     if (Process->QuotaUsage[PoolIndex] < Amount)
00084     {
00085         DPRINT1("WARNING: Process->QuotaUsage sanity check failed.\n");
00086     }
00087     else
00088     {
00089         InterlockedExchangeAdd((LONG*)&Process->QuotaUsage[PoolIndex],
00090                                -(LONG)Amount);
00091     }
00092 }
00093 
00094 #endif /* PS_QUOTA_ENABLE_QUOTA_CODE */
00095 
00096 
00097 /* FUNCTIONS ***************************************************************/
00098 
00099 VOID
00100 NTAPI
00101 INIT_FUNCTION
00102 PsInitializeQuotaSystem(VOID)
00103 {
00104     RtlZeroMemory(&PspDefaultQuotaBlock, sizeof(PspDefaultQuotaBlock));
00105     PspDefaultQuotaBlock.QuotaEntry[PagedPool].Limit = (SIZE_T)-1;
00106     PspDefaultQuotaBlock.QuotaEntry[NonPagedPool].Limit = (SIZE_T)-1;
00107     PspDefaultQuotaBlock.QuotaEntry[2].Limit = (SIZE_T)-1; /* Page file */
00108     PsGetCurrentProcess()->QuotaBlock = &PspDefaultQuotaBlock;
00109 }
00110 
00111 VOID
00112 NTAPI
00113 PspInheritQuota(PEPROCESS Process, PEPROCESS ParentProcess)
00114 {
00115     if (ParentProcess != NULL)
00116     {
00117         PEPROCESS_QUOTA_BLOCK QuotaBlock = ParentProcess->QuotaBlock;
00118 
00119         ASSERT(QuotaBlock != NULL);
00120 
00121         (void)InterlockedIncrementUL(&QuotaBlock->ReferenceCount);
00122 
00123         Process->QuotaBlock = QuotaBlock;
00124     }
00125     else
00126         Process->QuotaBlock = &PspDefaultQuotaBlock;
00127 }
00128 
00129 VOID
00130 NTAPI
00131 PspDestroyQuotaBlock(PEPROCESS Process)
00132 {
00133     PEPROCESS_QUOTA_BLOCK QuotaBlock = Process->QuotaBlock;
00134 
00135     if (QuotaBlock != &PspDefaultQuotaBlock &&
00136         InterlockedDecrementUL(&QuotaBlock->ReferenceCount) == 0)
00137     {
00138         ExFreePool(QuotaBlock);
00139     }
00140 }
00141 
00142 NTSTATUS
00143 NTAPI
00144 PsChargeProcessPageFileQuota(IN PEPROCESS Process,
00145                              IN SIZE_T Amount)
00146 {
00147     /* Don't do anything for the system process */
00148     if (Process == PsInitialSystemProcess) return STATUS_SUCCESS;
00149 
00150 #ifdef PS_QUOTA_ENABLE_QUOTA_CODE
00151     return PspChargeProcessQuotaSpecifiedPool(Process, 2, Amount);
00152 #else
00153     /* Otherwise, not implemented */
00154     UNIMPLEMENTED;
00155     return STATUS_SUCCESS;
00156 #endif
00157 }
00158 
00159 /*
00160  * @implemented
00161  */
00162 VOID
00163 NTAPI
00164 PsChargePoolQuota(IN PEPROCESS Process,
00165                   IN POOL_TYPE PoolType,
00166                   IN SIZE_T Amount)
00167 {
00168     NTSTATUS Status;
00169 
00170 #ifdef PS_QUOTA_ENABLE_QUOTA_CODE
00171     /* MS-documented IRQL requirement. Not yet enabled as it */
00172     /* needs verification that it does not break ReactOS, */
00173     ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
00174 #endif
00175 
00176     /* Don't do anything for the system process */
00177     if (Process == PsInitialSystemProcess) return;
00178 
00179     /* Charge the usage */
00180     Status = PsChargeProcessPoolQuota(Process, PoolType, Amount);
00181     if (!NT_SUCCESS(Status)) ExRaiseStatus(Status);
00182 }
00183 
00184 /*
00185  * @implemented
00186  */
00187 NTSTATUS
00188 NTAPI
00189 PsChargeProcessNonPagedPoolQuota(IN PEPROCESS Process,
00190                                  IN SIZE_T Amount)
00191 {
00192     /* Call the general function */
00193     return PsChargeProcessPoolQuota(Process, NonPagedPool, Amount);
00194 }
00195 
00196 /*
00197  * @implemented
00198  */
00199 NTSTATUS
00200 NTAPI
00201 PsChargeProcessPagedPoolQuota(IN PEPROCESS Process,
00202                               IN SIZE_T Amount)
00203 {
00204     /* Call the general function */
00205     return PsChargeProcessPoolQuota(Process, PagedPool, Amount);
00206 }
00207 
00208 /*
00209  * @implemented
00210  */
00211 NTSTATUS
00212 NTAPI
00213 PsChargeProcessPoolQuota(IN PEPROCESS Process,
00214                          IN POOL_TYPE PoolType,
00215                          IN SIZE_T Amount)
00216 {
00217     /* Don't do anything for the system process */
00218     if (Process == PsInitialSystemProcess) return STATUS_SUCCESS;
00219 
00220 #ifdef PS_QUOTA_ENABLE_QUOTA_CODE
00221     return PspChargeProcessQuotaSpecifiedPool(Process,
00222                                               (PoolType & PAGED_POOL_MASK),
00223                                               Amount);
00224 #else
00225     UNIMPLEMENTED;
00226     return STATUS_SUCCESS;
00227 #endif
00228 }
00229 
00230 /*
00231  * @unimplemented
00232  */
00233 VOID
00234 NTAPI
00235 PsReturnPoolQuota(IN PEPROCESS Process,
00236                   IN POOL_TYPE PoolType,
00237                   IN SIZE_T Amount)
00238 {
00239 #ifdef PS_QUOTA_ENABLE_QUOTA_CODE
00240     /* MS-documented IRQL requirement. Not yet enabled as it */
00241     /* needs verification that it does not break ReactOS, */
00242     ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
00243 #endif
00244 
00245     /* Don't do anything for the system process */
00246     if (Process == PsInitialSystemProcess) return;
00247 
00248 #ifdef PS_QUOTA_ENABLE_QUOTA_CODE
00249     PspReturnProcessQuotaSpecifiedPool(Process,
00250                                        (PoolType & PAGED_POOL_MASK),
00251                                        Amount);
00252 #else
00253     UNIMPLEMENTED;
00254 #endif
00255 }
00256 
00257 /*
00258  * @unimplemented
00259  */
00260 VOID
00261 NTAPI
00262 PsReturnProcessNonPagedPoolQuota(IN PEPROCESS Process,
00263                                  IN SIZE_T Amount)
00264 {
00265     /* Don't do anything for the system process */
00266     if (Process == PsInitialSystemProcess) return;
00267 
00268 #ifdef PS_QUOTA_ENABLE_QUOTA_CODE
00269     PsReturnPoolQuota(Process, NonPagedPool, Amount);
00270 #else
00271     UNIMPLEMENTED;
00272 #endif
00273 }
00274 
00275 /*
00276  * @unimplemented
00277  */
00278 VOID
00279 NTAPI
00280 PsReturnProcessPagedPoolQuota(IN PEPROCESS Process,
00281                               IN SIZE_T Amount)
00282 {
00283     /* Don't do anything for the system process */
00284     if (Process == PsInitialSystemProcess) return;
00285 
00286 #ifdef PS_QUOTA_ENABLE_QUOTA_CODE
00287     PsReturnPoolQuota(Process, PagedPool, Amount);
00288 #else
00289     UNIMPLEMENTED;
00290 #endif
00291 }
00292 
00293 NTSTATUS
00294 NTAPI
00295 PsReturnProcessPageFileQuota(IN PEPROCESS Process,
00296                              IN SIZE_T Amount)
00297 {
00298     /* Don't do anything for the system process */
00299     if (Process == PsInitialSystemProcess) return STATUS_SUCCESS;
00300 
00301 #ifdef PS_QUOTA_ENABLE_QUOTA_CODE
00302     PspReturnProcessQuotaSpecifiedPool(Process, 2, Amount);
00303 #else
00304     /* Otherwise, not implemented */
00305     UNIMPLEMENTED;
00306 #endif
00307     return STATUS_SUCCESS;
00308 }
00309 
00310 /* EOF */

Generated on Sat May 26 2012 04:36:32 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.