prevent buffer overflow, LoadString accepts the size of the buffer in TCHARs, not...
[reactos.git] / reactos / ntoskrnl / ps / notify.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ps/notify.c
5 * PURPOSE: Notifications
6 *
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
8 */
9
10 /* INCLUDES ****************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <internal/debug.h>
15
16 /* GLOBAL *******************************************************************/
17
18 #define MAX_THREAD_NOTIFY_ROUTINE_COUNT 8
19 #define TAG_KAPC TAG('k','p','a','p') /* kpap - kernel ps apc */
20
21 static ULONG PspThreadNotifyRoutineCount = 0;
22 static PCREATE_THREAD_NOTIFY_ROUTINE
23 PspThreadNotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT];
24
25 static PCREATE_PROCESS_NOTIFY_ROUTINE
26 PspProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT];
27
28 static PLOAD_IMAGE_NOTIFY_ROUTINE
29 PspLoadImageNotifyRoutine[MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT];
30
31 static PVOID PspLegoNotifyRoutine;
32
33 /* FUNCTIONS ***************************************************************/
34
35 /*
36 * @implemented
37 */
38 NTSTATUS
39 STDCALL
40 PsSetCreateProcessNotifyRoutine(IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
41 IN BOOLEAN Remove)
42 {
43 ULONG i;
44
45 /* Check if it's a removal or addition */
46 if (Remove)
47 {
48 /* Loop the routines */
49 for(i=0;i<MAX_PROCESS_NOTIFY_ROUTINE_COUNT;i++)
50 {
51 /* Check for a match */
52 if ((PVOID)PspProcessNotifyRoutine[i] == (PVOID)NotifyRoutine)
53 {
54 /* Remove and return */
55 PspProcessNotifyRoutine[i] = NULL;
56 return(STATUS_SUCCESS);
57 }
58 }
59 }
60 else
61 {
62 /* Loop the routines */
63 for(i=0;i<MAX_PROCESS_NOTIFY_ROUTINE_COUNT;i++)
64 {
65 /* Find an empty one */
66 if (PspProcessNotifyRoutine[i] == NULL)
67 {
68 /* Add it */
69 PspProcessNotifyRoutine[i] = NotifyRoutine;
70 return STATUS_SUCCESS;
71 }
72 }
73 }
74
75 /* Nothing found */
76 return STATUS_INVALID_PARAMETER;
77 }
78
79 /*
80 * @implemented
81 */
82 ULONG
83 STDCALL
84 PsSetLegoNotifyRoutine(PVOID LegoNotifyRoutine)
85 {
86 /* Set the System-Wide Lego Routine */
87 PspLegoNotifyRoutine = LegoNotifyRoutine;
88
89 /* Return the location to the Lego Data */
90 return FIELD_OFFSET(KTHREAD, LegoData);
91 }
92
93 /*
94 * @implemented
95 */
96 NTSTATUS
97 STDCALL
98 PsRemoveLoadImageNotifyRoutine(IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine)
99 {
100 ULONG i;
101
102 /* Loop the routines */
103 for(i=0;i<MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT;i++)
104 {
105 /* Check for a match */
106 if ((PVOID)PspLoadImageNotifyRoutine[i] == (PVOID)NotifyRoutine)
107 {
108 /* Remove and return */
109 PspLoadImageNotifyRoutine[i] = NULL;
110 return(STATUS_SUCCESS);
111 }
112 }
113
114 /* Nothing found */
115 return STATUS_INVALID_PARAMETER;
116 }
117
118 /*
119 * @implemented
120 */
121 NTSTATUS
122 STDCALL
123 PsSetLoadImageNotifyRoutine(IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine)
124 {
125 ULONG i;
126
127 /* Loop the routines */
128 for (i = 0; i < MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT; i++)
129 {
130 /* Find an empty one */
131 if (PspLoadImageNotifyRoutine[i] == NULL)
132 {
133 /* Add it */
134 PspLoadImageNotifyRoutine[i] = NotifyRoutine;
135 return STATUS_SUCCESS;
136 }
137 }
138
139 /* Nothing found */
140 return STATUS_INVALID_PARAMETER;
141 }
142
143 /*
144 * @implemented
145 */
146 NTSTATUS
147 STDCALL
148 PsRemoveCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine)
149 {
150 ULONG i;
151
152 /* Loop the routines */
153 for(i=0;i<MAX_THREAD_NOTIFY_ROUTINE_COUNT;i++)
154 {
155 /* Check for a match */
156 if ((PVOID)PspThreadNotifyRoutine[i] == (PVOID)NotifyRoutine)
157 {
158 /* Remove and return */
159 PspThreadNotifyRoutine[i] = NULL;
160 return(STATUS_SUCCESS);
161 }
162 }
163
164 /* Nothing found */
165 return STATUS_INVALID_PARAMETER;
166 }
167
168 /*
169 * @implemented
170 */
171 NTSTATUS
172 STDCALL
173 PsSetCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine)
174 {
175 if (PspThreadNotifyRoutineCount >= MAX_THREAD_NOTIFY_ROUTINE_COUNT)
176 {
177 return(STATUS_INSUFFICIENT_RESOURCES);
178 }
179
180 PspThreadNotifyRoutine[PspThreadNotifyRoutineCount] = NotifyRoutine;
181 PspThreadNotifyRoutineCount++;
182
183 return(STATUS_SUCCESS);
184 }
185
186 VOID
187 STDCALL
188 PspRunCreateThreadNotifyRoutines(PETHREAD CurrentThread,
189 BOOLEAN Create)
190 {
191 ULONG i;
192 CLIENT_ID Cid = CurrentThread->Cid;
193
194 for (i = 0; i < PspThreadNotifyRoutineCount; i++)
195 {
196 PspThreadNotifyRoutine[i](Cid.UniqueProcess, Cid.UniqueThread, Create);
197 }
198 }
199
200 VOID
201 STDCALL
202 PspRunCreateProcessNotifyRoutines(PEPROCESS CurrentProcess,
203 BOOLEAN Create)
204 {
205 ULONG i;
206 HANDLE ProcessId = (HANDLE)CurrentProcess->UniqueProcessId;
207 HANDLE ParentId = CurrentProcess->InheritedFromUniqueProcessId;
208
209 for(i = 0; i < MAX_PROCESS_NOTIFY_ROUTINE_COUNT; ++i)
210 {
211 if(PspProcessNotifyRoutine[i])
212 {
213 PspProcessNotifyRoutine[i](ParentId, ProcessId, Create);
214 }
215 }
216 }
217
218 VOID
219 STDCALL
220 PspRunLoadImageNotifyRoutines(PUNICODE_STRING FullImageName,
221 HANDLE ProcessId,
222 PIMAGE_INFO ImageInfo)
223 {
224 ULONG i;
225
226 for (i = 0; i < MAX_PROCESS_NOTIFY_ROUTINE_COUNT; ++ i)
227 {
228 if (PspLoadImageNotifyRoutine[i])
229 {
230 PspLoadImageNotifyRoutine[i](FullImageName, ProcessId, ImageInfo);
231 }
232 }
233 }
234
235 /* EOF */