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

psnotify.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 doxygen 1.7.6.1

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