Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpsnotify.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/ps/notify.c 00005 * PURPOSE: Process Manager: Callbacks to Registered Clients (Drivers) 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 * Thomas Weidenmueller (w3seek@reactos.org) 00008 */ 00009 00010 /* INCLUDES ******************************************************************/ 00011 00012 #include <ntoskrnl.h> 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 /* GLOBALS *******************************************************************/ 00017 00018 BOOLEAN PsImageNotifyEnabled = FALSE; 00019 ULONG PspThreadNotifyRoutineCount, PspProcessNotifyRoutineCount; 00020 ULONG PspLoadImageNotifyRoutineCount; 00021 EX_CALLBACK PspThreadNotifyRoutine[PSP_MAX_CREATE_THREAD_NOTIFY]; 00022 EX_CALLBACK PspProcessNotifyRoutine[PSP_MAX_CREATE_PROCESS_NOTIFY]; 00023 EX_CALLBACK PspLoadImageNotifyRoutine[PSP_MAX_LOAD_IMAGE_NOTIFY]; 00024 PLEGO_NOTIFY_ROUTINE PspLegoNotifyRoutine; 00025 00026 /* PUBLIC FUNCTIONS **********************************************************/ 00027 00028 /* 00029 * @implemented 00030 */ 00031 NTSTATUS 00032 NTAPI 00033 PsSetCreateProcessNotifyRoutine(IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine, 00034 IN BOOLEAN Remove) 00035 { 00036 ULONG i; 00037 PEX_CALLBACK_ROUTINE_BLOCK CallBack; 00038 PAGED_CODE(); 00039 00040 /* Check if we're removing */ 00041 if (Remove) 00042 { 00043 /* Loop all the routines */ 00044 for (i = 0; i < PSP_MAX_CREATE_PROCESS_NOTIFY; i++) 00045 { 00046 /* Reference the callback block */ 00047 CallBack = ExReferenceCallBackBlock(&PspProcessNotifyRoutine[i]); 00048 if (!CallBack) continue; 00049 00050 /* Check it this is a matching block */ 00051 if (ExGetCallBackBlockRoutine(CallBack) != (PVOID)NotifyRoutine) 00052 { 00053 /* It's not, try the next one */ 00054 continue; 00055 } 00056 00057 /* It is, clear the current routine */ 00058 if (ExCompareExchangeCallBack(&PspProcessNotifyRoutine[i], 00059 NULL, 00060 CallBack)) 00061 { 00062 /* Decrement the number of routines */ 00063 InterlockedDecrement((PLONG)&PspProcessNotifyRoutineCount); 00064 00065 /* Dereference the block */ 00066 ExDereferenceCallBackBlock(&PspProcessNotifyRoutine[i], 00067 CallBack); 00068 00069 /* Wait for actice callbacks */ 00070 ExWaitForCallBacks(CallBack); 00071 00072 /* Free the callback and exit */ 00073 ExFreeCallBack (CallBack); 00074 return STATUS_SUCCESS; 00075 } 00076 00077 /* Dereference the block */ 00078 ExDereferenceCallBackBlock(&PspProcessNotifyRoutine[i], 00079 CallBack); 00080 } 00081 00082 /* We didn't find any matching block */ 00083 return STATUS_PROCEDURE_NOT_FOUND; 00084 } 00085 else 00086 { 00087 /* Allocate a callback */ 00088 CallBack = ExAllocateCallBack((PVOID)NotifyRoutine, NULL); 00089 if (!CallBack) return STATUS_INSUFFICIENT_RESOURCES; 00090 00091 /* Loop all callbacks */ 00092 for (i = 0; i < PSP_MAX_CREATE_PROCESS_NOTIFY; i++) 00093 { 00094 /* Add this routine if it's an empty slot */ 00095 if (ExCompareExchangeCallBack(&PspProcessNotifyRoutine[i], 00096 CallBack, 00097 NULL)) 00098 { 00099 /* Found and inserted into an empty slot, return */ 00100 InterlockedIncrement((PLONG)&PspProcessNotifyRoutineCount); 00101 return STATUS_SUCCESS; 00102 } 00103 } 00104 00105 /* We didn't find a free slot, free the callback and fail */ 00106 ExFreeCallBack(CallBack); 00107 return STATUS_INVALID_PARAMETER; 00108 } 00109 } 00110 00111 /* 00112 * @implemented 00113 */ 00114 ULONG 00115 NTAPI 00116 PsSetLegoNotifyRoutine(PVOID LegoNotifyRoutine) 00117 { 00118 /* Set the System-Wide Lego Routine */ 00119 PspLegoNotifyRoutine = LegoNotifyRoutine; 00120 00121 /* Return the location to the Lego Data */ 00122 return FIELD_OFFSET(KTHREAD, LegoData); 00123 } 00124 00125 /* 00126 * @implemented 00127 */ 00128 NTSTATUS 00129 NTAPI 00130 PsRemoveLoadImageNotifyRoutine(IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine) 00131 { 00132 ULONG i; 00133 PEX_CALLBACK_ROUTINE_BLOCK CallBack; 00134 PAGED_CODE(); 00135 00136 /* Loop all callbacks */ 00137 for (i = 0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; i++) 00138 { 00139 /* Reference this slot */ 00140 CallBack = ExReferenceCallBackBlock(&PspLoadImageNotifyRoutine[i]); 00141 if (CallBack) 00142 { 00143 /* Check for a match */ 00144 if (ExGetCallBackBlockRoutine(CallBack) == (PVOID)NotifyRoutine) 00145 { 00146 /* Try removing it if it matches */ 00147 if (ExCompareExchangeCallBack(&PspLoadImageNotifyRoutine[i], 00148 NULL, 00149 CallBack)) 00150 { 00151 /* We removed it, now dereference the block */ 00152 InterlockedDecrement((PLONG)&PspLoadImageNotifyRoutineCount); 00153 ExDereferenceCallBackBlock(&PspLoadImageNotifyRoutine[i], 00154 CallBack); 00155 00156 /* Wait for active callbacks */ 00157 ExWaitForCallBacks(CallBack); 00158 00159 /* Free the callback and return */ 00160 ExFreeCallBack(CallBack); 00161 return STATUS_SUCCESS; 00162 } 00163 } 00164 00165 /* Dereference the callback */ 00166 ExDereferenceCallBackBlock(&PspLoadImageNotifyRoutine[i], CallBack); 00167 } 00168 } 00169 00170 /* Nothing found to remove */ 00171 return STATUS_PROCEDURE_NOT_FOUND; 00172 } 00173 00174 /* 00175 * @implemented 00176 */ 00177 NTSTATUS 00178 NTAPI 00179 PsSetLoadImageNotifyRoutine(IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine) 00180 { 00181 ULONG i; 00182 PEX_CALLBACK_ROUTINE_BLOCK CallBack; 00183 PAGED_CODE(); 00184 00185 /* Allocate a callback */ 00186 CallBack = ExAllocateCallBack((PVOID)NotifyRoutine, NULL); 00187 if (!CallBack) return STATUS_INSUFFICIENT_RESOURCES; 00188 00189 /* Loop callbacks */ 00190 for (i = 0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; i++) 00191 { 00192 /* Add this entry if the slot is empty */ 00193 if (ExCompareExchangeCallBack(&PspLoadImageNotifyRoutine[i], 00194 CallBack, 00195 NULL)) 00196 { 00197 /* Return success */ 00198 InterlockedIncrement((PLONG)&PspLoadImageNotifyRoutineCount); 00199 PsImageNotifyEnabled = TRUE; 00200 return STATUS_SUCCESS; 00201 } 00202 } 00203 00204 /* No free space found, fail */ 00205 ExFreeCallBack(CallBack); 00206 return STATUS_INSUFFICIENT_RESOURCES; 00207 } 00208 00209 /* 00210 * @implemented 00211 */ 00212 NTSTATUS 00213 NTAPI 00214 PsRemoveCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine) 00215 { 00216 ULONG i; 00217 PEX_CALLBACK_ROUTINE_BLOCK CallBack; 00218 PAGED_CODE(); 00219 00220 /* Loop all callbacks */ 00221 for (i = 0; i < PSP_MAX_CREATE_THREAD_NOTIFY; i++) 00222 { 00223 /* Reference this slot */ 00224 CallBack = ExReferenceCallBackBlock(&PspThreadNotifyRoutine[i]); 00225 if (CallBack) 00226 { 00227 /* Check for a match */ 00228 if (ExGetCallBackBlockRoutine(CallBack) == (PVOID)NotifyRoutine) 00229 { 00230 /* Try removing it if it matches */ 00231 if (ExCompareExchangeCallBack(&PspThreadNotifyRoutine[i], 00232 NULL, 00233 CallBack)) 00234 { 00235 /* We removed it, now dereference the block */ 00236 InterlockedDecrement((PLONG)&PspThreadNotifyRoutineCount); 00237 ExDereferenceCallBackBlock(&PspThreadNotifyRoutine[i], 00238 CallBack); 00239 00240 /* Wait for active callbacks */ 00241 ExWaitForCallBacks(CallBack); 00242 00243 /* Free the callback and return */ 00244 ExFreeCallBack(CallBack); 00245 return STATUS_SUCCESS; 00246 } 00247 } 00248 00249 /* Dereference the callback */ 00250 ExDereferenceCallBackBlock(&PspThreadNotifyRoutine[i], CallBack); 00251 } 00252 } 00253 00254 /* Nothing found to remove */ 00255 return STATUS_PROCEDURE_NOT_FOUND; 00256 } 00257 00258 /* 00259 * @implemented 00260 */ 00261 NTSTATUS 00262 NTAPI 00263 PsSetCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine) 00264 { 00265 ULONG i; 00266 PEX_CALLBACK_ROUTINE_BLOCK CallBack; 00267 PAGED_CODE(); 00268 00269 /* Allocate a callback */ 00270 CallBack = ExAllocateCallBack((PVOID)NotifyRoutine, NULL); 00271 if (!CallBack) return STATUS_INSUFFICIENT_RESOURCES; 00272 00273 /* Loop callbacks */ 00274 for (i = 0; i < PSP_MAX_CREATE_THREAD_NOTIFY; i++) 00275 { 00276 /* Add this entry if the slot is empty */ 00277 if (ExCompareExchangeCallBack(&PspThreadNotifyRoutine[i], 00278 CallBack, 00279 NULL)) 00280 { 00281 /* Return success */ 00282 InterlockedIncrement((PLONG)&PspThreadNotifyRoutineCount); 00283 return STATUS_SUCCESS; 00284 } 00285 } 00286 00287 /* No free space found, fail */ 00288 ExFreeCallBack(CallBack); 00289 return STATUS_INSUFFICIENT_RESOURCES; 00290 } 00291 00292 /* EOF */ Generated on Sun May 27 2012 04:37:41 for ReactOS by
1.7.6.1
|