Major refactoring of the exception handling code + misc fixes:
[reactos.git] / reactos / ntoskrnl / rtl / libsupp.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/rtl/libsupp.c
5 * PURPOSE: RTL Support Routines
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * Gunnar Dalsnes
8 */
9
10 /* INCLUDES ******************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <internal/debug.h>
15
16 extern ULONG NtGlobalFlag;
17
18 /* FUNCTIONS *****************************************************************/
19
20 BOOLEAN
21 NTAPI
22 RtlpCheckForActiveDebugger(VOID)
23 {
24 /* This check is meaningless in kernel-mode */
25 return TRUE;
26 }
27
28 KPROCESSOR_MODE
29 STDCALL
30 RtlpGetMode()
31 {
32 return KernelMode;
33 }
34
35 PVOID
36 STDCALL
37 RtlpAllocateMemory(UINT Bytes,
38 ULONG Tag)
39 {
40 return ExAllocatePoolWithTag(PagedPool,
41 (SIZE_T)Bytes,
42 Tag);
43 }
44
45
46 VOID
47 STDCALL
48 RtlpFreeMemory(PVOID Mem,
49 ULONG Tag)
50 {
51 ExFreePoolWithTag(Mem,
52 Tag);
53 }
54
55 /*
56 * @implemented
57 */
58 VOID STDCALL
59 RtlAcquirePebLock(VOID)
60 {
61
62 }
63
64 /*
65 * @implemented
66 */
67 VOID STDCALL
68 RtlReleasePebLock(VOID)
69 {
70
71 }
72
73 NTSTATUS
74 STDCALL
75 LdrShutdownThread(VOID)
76 {
77 return STATUS_SUCCESS;
78 }
79
80
81 PPEB
82 STDCALL
83 RtlpCurrentPeb(VOID)
84 {
85 return ((PEPROCESS)(KeGetCurrentThread()->ApcState.Process))->Peb;
86 }
87
88 NTSTATUS
89 STDCALL
90 RtlDeleteHeapLock(
91 PRTL_CRITICAL_SECTION CriticalSection)
92 {
93 return STATUS_SUCCESS;
94 }
95
96 NTSTATUS
97 STDCALL
98 RtlEnterHeapLock(
99 PRTL_CRITICAL_SECTION CriticalSection)
100 {
101 ExAcquireFastMutex((PFAST_MUTEX) CriticalSection);
102 return STATUS_SUCCESS;
103 }
104
105 NTSTATUS
106 STDCALL
107 RtlInitializeHeapLock(
108 PRTL_CRITICAL_SECTION CriticalSection)
109 {
110 ExInitializeFastMutex((PFAST_MUTEX)CriticalSection );
111 return STATUS_SUCCESS;
112 }
113
114 NTSTATUS
115 STDCALL
116 RtlLeaveHeapLock(
117 PRTL_CRITICAL_SECTION CriticalSection)
118 {
119 ExReleaseFastMutex((PFAST_MUTEX) CriticalSection );
120 return STATUS_SUCCESS;
121 }
122
123 #ifdef DBG
124 VOID FASTCALL
125 CHECK_PAGED_CODE_RTL(char *file, int line)
126 {
127 if(KeGetCurrentIrql() > APC_LEVEL)
128 {
129 DbgPrint("%s:%i: Pagable code called at IRQL > APC_LEVEL (%d)\n", file, line, KeGetCurrentIrql());
130 KEBUGCHECK(0);
131 }
132 }
133 #endif
134
135 VOID
136 NTAPI
137 RtlpCheckLogException(IN PEXCEPTION_RECORD ExceptionRecord,
138 IN PCONTEXT ContextRecord,
139 IN PVOID ContextData,
140 IN ULONG Size)
141 {
142 /* Check the global flag */
143 if (NtGlobalFlag & FLG_ENABLE_EXCEPTION_LOGGING)
144 {
145 /* FIXME: Log this exception */
146 }
147 }
148
149 BOOLEAN
150 NTAPI
151 RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame,
152 IN ULONG_PTR RegistrationFrameEnd,
153 IN OUT PULONG_PTR StackLow,
154 IN OUT PULONG_PTR StackHigh)
155 {
156 PKPRCB Prcb;
157 ULONG_PTR DpcStack;
158
159 /* Check if we are at DISPATCH or higher */
160 if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
161 {
162 /* Get the PRCB and DPC Stack */
163 Prcb = KeGetCurrentPrcb();
164 DpcStack = (ULONG_PTR)Prcb->DpcStack;
165
166 /* Check if we are in a DPC and the stack matches */
167 if ((Prcb->DpcRoutineActive) &&
168 (RegistrationFrameEnd <= DpcStack) &&
169 ((ULONG_PTR)RegistrationFrame >= DpcStack - 4096))
170 {
171 /* Update the limits to the DPC Stack's */
172 *StackHigh = DpcStack;
173 *StackLow = DpcStack - 4096;
174 return TRUE;
175 }
176 }
177
178 /* Not in DPC stack */
179 return FALSE;
180 }
181
182 /* RTL Atom Tables ************************************************************/
183
184 NTSTATUS
185 RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable)
186 {
187 ExInitializeFastMutex(&AtomTable->FastMutex);
188
189 return STATUS_SUCCESS;
190 }
191
192
193 VOID
194 RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable)
195 {
196 }
197
198
199 BOOLEAN
200 RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable)
201 {
202 ExAcquireFastMutex(&AtomTable->FastMutex);
203 return TRUE;
204 }
205
206 VOID
207 RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable)
208 {
209 ExReleaseFastMutex(&AtomTable->FastMutex);
210 }
211
212 BOOLEAN
213 RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
214 {
215 AtomTable->ExHandleTable = ExCreateHandleTable(NULL);
216 return (AtomTable->ExHandleTable != NULL);
217 }
218
219 static VOID STDCALL
220 AtomDeleteHandleCallback(PHANDLE_TABLE HandleTable,
221 PVOID Object,
222 ULONG GrantedAccess,
223 PVOID Context)
224 {
225 return;
226 }
227
228 VOID
229 RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
230 {
231 if (AtomTable->ExHandleTable)
232 {
233 ExDestroyHandleTable(AtomTable->ExHandleTable,
234 AtomDeleteHandleCallback,
235 AtomTable);
236 AtomTable->ExHandleTable = NULL;
237 }
238 }
239
240 PRTL_ATOM_TABLE
241 RtlpAllocAtomTable(ULONG Size)
242 {
243 PRTL_ATOM_TABLE Table = ExAllocatePool(NonPagedPool,
244 Size);
245 if (Table != NULL)
246 {
247 RtlZeroMemory(Table,
248 Size);
249 }
250
251 return Table;
252 }
253
254 VOID
255 RtlpFreeAtomTable(PRTL_ATOM_TABLE AtomTable)
256 {
257 ExFreePool(AtomTable);
258 }
259
260 PRTL_ATOM_TABLE_ENTRY
261 RtlpAllocAtomTableEntry(ULONG Size)
262 {
263 PRTL_ATOM_TABLE_ENTRY Entry = ExAllocatePool(NonPagedPool,
264 Size);
265 if (Entry != NULL)
266 {
267 RtlZeroMemory(Entry,
268 Size);
269 }
270
271 return Entry;
272 }
273
274 VOID
275 RtlpFreeAtomTableEntry(PRTL_ATOM_TABLE_ENTRY Entry)
276 {
277 ExFreePool(Entry);
278 }
279
280 VOID
281 RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry)
282 {
283 ExDestroyHandle(AtomTable->ExHandleTable,
284 (HANDLE)((ULONG_PTR)Entry->HandleIndex << 2));
285 }
286
287 BOOLEAN
288 RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry)
289 {
290 HANDLE_TABLE_ENTRY ExEntry;
291 HANDLE Handle;
292 USHORT HandleIndex;
293
294 ExEntry.u1.Object = Entry;
295 ExEntry.u2.GrantedAccess = 0x1; /* FIXME - valid handle */
296
297 Handle = ExCreateHandle(AtomTable->ExHandleTable,
298 &ExEntry);
299 if (Handle != NULL)
300 {
301 HandleIndex = (USHORT)((ULONG_PTR)Handle >> 2);
302 /* FIXME - Handle Indexes >= 0xC000 ?! */
303 if ((ULONG_PTR)HandleIndex >> 2 < 0xC000)
304 {
305 Entry->HandleIndex = HandleIndex;
306 Entry->Atom = 0xC000 + HandleIndex;
307
308 return TRUE;
309 }
310 else
311 ExDestroyHandle(AtomTable->ExHandleTable,
312 Handle);
313 }
314
315 return FALSE;
316 }
317
318 PRTL_ATOM_TABLE_ENTRY
319 RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable, ULONG Index)
320 {
321 PHANDLE_TABLE_ENTRY ExEntry;
322 PRTL_ATOM_TABLE_ENTRY Entry = NULL;
323
324 /* NOTE: There's no need to explicitly enter a critical region because it's
325 guaranteed that we're in a critical region right now (as we hold
326 the atom table lock) */
327
328 ExEntry = ExMapHandleToPointer(AtomTable->ExHandleTable,
329 (HANDLE)((ULONG_PTR)Index << 2));
330 if (ExEntry != NULL)
331 {
332 Entry = ExEntry->u1.Object;
333
334 ExUnlockHandleTableEntry(AtomTable->ExHandleTable,
335 ExEntry);
336 }
337
338 return Entry;
339 }
340
341 /* FIXME - RtlpCreateUnicodeString is obsolete and should be removed ASAP! */
342 BOOLEAN FASTCALL
343 RtlpCreateUnicodeString(
344 IN OUT PUNICODE_STRING UniDest,
345 IN PCWSTR Source,
346 IN POOL_TYPE PoolType)
347 {
348 ULONG Length;
349
350 Length = (wcslen (Source) + 1) * sizeof(WCHAR);
351 UniDest->Buffer = ExAllocatePoolWithTag(PoolType, Length, TAG('U', 'S', 'T', 'R'));
352 if (UniDest->Buffer == NULL)
353 return FALSE;
354
355 RtlCopyMemory (UniDest->Buffer,
356 Source,
357 Length);
358
359 UniDest->MaximumLength = Length;
360 UniDest->Length = Length - sizeof (WCHAR);
361
362 return TRUE;
363 }
364
365 /* EOF */