Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenquota.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
1.7.6.1
|