- Fix dozens of missing typecast errors.
[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(ULONG 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 BOOLEAN
192 NTAPI
193 RtlpCaptureStackLimits(IN ULONG_PTR Ebp,
194 IN ULONG_PTR *StackBegin,
195 IN ULONG_PTR *StackEnd)
196 {
197 PKTHREAD Thread = KeGetCurrentThread();
198
199 /* FIXME: Super native implementation */
200
201 /* Start with defaults */
202 *StackBegin = Thread->StackLimit;
203 *StackEnd = (ULONG_PTR)Thread->StackBase;
204
205 /* Check if we seem to be on the DPC stack */
206 if ((*StackBegin > Ebp) || (Ebp > *StackEnd))
207 {
208 /* FIXME: TODO */
209 ASSERT(FALSE);
210 }
211
212 /* Return success */
213 return TRUE;
214 }
215
216 /* RTL Atom Tables ************************************************************/
217
218 NTSTATUS
219 RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable)
220 {
221 ExInitializeFastMutex(&AtomTable->FastMutex);
222
223 return STATUS_SUCCESS;
224 }
225
226
227 VOID
228 RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable)
229 {
230 }
231
232
233 BOOLEAN
234 RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable)
235 {
236 ExAcquireFastMutex(&AtomTable->FastMutex);
237 return TRUE;
238 }
239
240 VOID
241 RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable)
242 {
243 ExReleaseFastMutex(&AtomTable->FastMutex);
244 }
245
246 BOOLEAN
247 RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
248 {
249 AtomTable->ExHandleTable = ExCreateHandleTable(NULL);
250 return (AtomTable->ExHandleTable != NULL);
251 }
252
253 VOID
254 RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
255 {
256 if (AtomTable->ExHandleTable)
257 {
258 ExSweepHandleTable(AtomTable->ExHandleTable,
259 NULL,
260 NULL);
261 ExDestroyHandleTable(AtomTable->ExHandleTable);
262 AtomTable->ExHandleTable = NULL;
263 }
264 }
265
266 PRTL_ATOM_TABLE
267 RtlpAllocAtomTable(ULONG Size)
268 {
269 PRTL_ATOM_TABLE Table = ExAllocatePool(NonPagedPool,
270 Size);
271 if (Table != NULL)
272 {
273 RtlZeroMemory(Table,
274 Size);
275 }
276
277 return Table;
278 }
279
280 VOID
281 RtlpFreeAtomTable(PRTL_ATOM_TABLE AtomTable)
282 {
283 ExFreePool(AtomTable);
284 }
285
286 PRTL_ATOM_TABLE_ENTRY
287 RtlpAllocAtomTableEntry(ULONG Size)
288 {
289 PRTL_ATOM_TABLE_ENTRY Entry = ExAllocatePool(NonPagedPool,
290 Size);
291 if (Entry != NULL)
292 {
293 RtlZeroMemory(Entry,
294 Size);
295 }
296
297 return Entry;
298 }
299
300 VOID
301 RtlpFreeAtomTableEntry(PRTL_ATOM_TABLE_ENTRY Entry)
302 {
303 ExFreePool(Entry);
304 }
305
306 VOID
307 RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry)
308 {
309 ExDestroyHandle(AtomTable->ExHandleTable,
310 (HANDLE)((ULONG_PTR)Entry->HandleIndex << 2));
311 }
312
313 BOOLEAN
314 RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry)
315 {
316 HANDLE_TABLE_ENTRY ExEntry;
317 HANDLE Handle;
318 USHORT HandleIndex;
319
320 ExEntry.Object = Entry;
321 ExEntry.GrantedAccess = 0x1; /* FIXME - valid handle */
322
323 Handle = ExCreateHandle(AtomTable->ExHandleTable,
324 &ExEntry);
325 if (Handle != NULL)
326 {
327 HandleIndex = (USHORT)((ULONG_PTR)Handle >> 2);
328 /* FIXME - Handle Indexes >= 0xC000 ?! */
329 if ((ULONG_PTR)HandleIndex >> 2 < 0xC000)
330 {
331 Entry->HandleIndex = HandleIndex;
332 Entry->Atom = 0xC000 + HandleIndex;
333
334 return TRUE;
335 }
336 else
337 ExDestroyHandle(AtomTable->ExHandleTable,
338 Handle);
339 }
340
341 return FALSE;
342 }
343
344 PRTL_ATOM_TABLE_ENTRY
345 RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable, ULONG Index)
346 {
347 PHANDLE_TABLE_ENTRY ExEntry;
348 PRTL_ATOM_TABLE_ENTRY Entry = NULL;
349
350 /* NOTE: There's no need to explicitly enter a critical region because it's
351 guaranteed that we're in a critical region right now (as we hold
352 the atom table lock) */
353
354 ExEntry = ExMapHandleToPointer(AtomTable->ExHandleTable,
355 (HANDLE)((ULONG_PTR)Index << 2));
356 if (ExEntry != NULL)
357 {
358 Entry = ExEntry->Object;
359
360 ExUnlockHandleTableEntry(AtomTable->ExHandleTable,
361 ExEntry);
362 }
363
364 return Entry;
365 }
366
367 /* FIXME - RtlpCreateUnicodeString is obsolete and should be removed ASAP! */
368 BOOLEAN FASTCALL
369 RtlpCreateUnicodeString(
370 IN OUT PUNICODE_STRING UniDest,
371 IN PCWSTR Source,
372 IN POOL_TYPE PoolType)
373 {
374 ULONG Length;
375
376 Length = (wcslen (Source) + 1) * sizeof(WCHAR);
377 UniDest->Buffer = ExAllocatePoolWithTag(PoolType, Length, TAG('U', 'S', 'T', 'R'));
378 if (UniDest->Buffer == NULL)
379 return FALSE;
380
381 RtlCopyMemory (UniDest->Buffer,
382 Source,
383 Length);
384
385 UniDest->MaximumLength = (USHORT)Length;
386 UniDest->Length = (USHORT)Length - sizeof (WCHAR);
387
388 return TRUE;
389 }
390
391 /*
392 * Ldr Resource support code
393 */
394
395 IMAGE_RESOURCE_DIRECTORY *find_entry_by_name( IMAGE_RESOURCE_DIRECTORY *dir,
396 LPCWSTR name, void *root,
397 int want_dir );
398 IMAGE_RESOURCE_DIRECTORY *find_entry_by_id( IMAGE_RESOURCE_DIRECTORY *dir,
399 USHORT id, void *root, int want_dir );
400 IMAGE_RESOURCE_DIRECTORY *find_first_entry( IMAGE_RESOURCE_DIRECTORY *dir,
401 void *root, int want_dir );
402
403 /**********************************************************************
404 * find_entry
405 *
406 * Find a resource entry
407 */
408 NTSTATUS find_entry( PVOID BaseAddress, LDR_RESOURCE_INFO *info,
409 ULONG level, void **ret, int want_dir )
410 {
411 ULONG size;
412 void *root;
413 IMAGE_RESOURCE_DIRECTORY *resdirptr;
414
415 root = RtlImageDirectoryEntryToData( BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size );
416 if (!root) return STATUS_RESOURCE_DATA_NOT_FOUND;
417 resdirptr = root;
418
419 if (!level--) goto done;
420 if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Type, root, want_dir || level )))
421 return STATUS_RESOURCE_TYPE_NOT_FOUND;
422 if (!level--) return STATUS_SUCCESS;
423
424 resdirptr = *ret;
425 if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Name, root, want_dir || level )))
426 return STATUS_RESOURCE_NAME_NOT_FOUND;
427 if (!level--) return STATUS_SUCCESS;
428 if (level) return STATUS_INVALID_PARAMETER; /* level > 3 */
429
430 resdirptr = *ret;
431
432 if ((*ret = find_first_entry( resdirptr, root, want_dir ))) return STATUS_SUCCESS;
433
434 return STATUS_RESOURCE_DATA_NOT_FOUND;
435
436 done:
437 *ret = resdirptr;
438 return STATUS_SUCCESS;
439 }
440
441
442 /* EOF */