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