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)
10 /* INCLUDES ******************************************************************/
14 #include <internal/debug.h>
16 extern ULONG NtGlobalFlag
;
18 /* FUNCTIONS *****************************************************************/
22 RtlpCheckForActiveDebugger(BOOLEAN Type
)
24 /* This check is meaningless in kernel-mode */
30 RtlpSetInDbgPrint(IN BOOLEAN NewValue
)
32 /* This check is meaningless in kernel-mode */
45 RtlpAllocateMemory(ULONG Bytes
,
48 return ExAllocatePoolWithTag(PagedPool
,
56 RtlpFreeMemory(PVOID Mem
,
59 ExFreePoolWithTag(Mem
,
67 RtlAcquirePebLock(VOID
)
76 RtlReleasePebLock(VOID
)
83 LdrShutdownThread(VOID
)
85 return STATUS_SUCCESS
;
93 return ((PEPROCESS
)(KeGetCurrentThread()->ApcState
.Process
))->Peb
;
99 PRTL_CRITICAL_SECTION CriticalSection
)
102 return STATUS_SUCCESS
;
108 PRTL_CRITICAL_SECTION CriticalSection
)
111 return STATUS_SUCCESS
;
116 RtlInitializeHeapLock(
117 PRTL_CRITICAL_SECTION CriticalSection
)
120 return STATUS_SUCCESS
;
126 PRTL_CRITICAL_SECTION CriticalSection
)
129 return STATUS_SUCCESS
;
134 CHECK_PAGED_CODE_RTL(char *file
, int line
)
136 if(KeGetCurrentIrql() > APC_LEVEL
)
138 DbgPrint("%s:%i: Pagable code called at IRQL > APC_LEVEL (%d)\n", file
, line
, KeGetCurrentIrql());
146 RtlpCheckLogException(IN PEXCEPTION_RECORD ExceptionRecord
,
147 IN PCONTEXT ContextRecord
,
148 IN PVOID ContextData
,
151 /* Check the global flag */
152 if (NtGlobalFlag
& FLG_ENABLE_EXCEPTION_LOGGING
)
154 /* FIXME: Log this exception */
160 RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame
,
161 IN ULONG_PTR RegistrationFrameEnd
,
162 IN OUT PULONG_PTR StackLow
,
163 IN OUT PULONG_PTR StackHigh
)
168 /* Check if we are at DISPATCH or higher */
169 if (KeGetCurrentIrql() >= DISPATCH_LEVEL
)
171 /* Get the PRCB and DPC Stack */
172 Prcb
= KeGetCurrentPrcb();
173 DpcStack
= (ULONG_PTR
)Prcb
->DpcStack
;
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))
180 /* Update the limits to the DPC Stack's */
181 *StackHigh
= DpcStack
;
182 *StackLow
= DpcStack
- 4096;
187 /* Not in DPC stack */
193 RtlpCaptureStackLimits(IN ULONG_PTR Ebp
,
194 IN ULONG_PTR
*StackBegin
,
195 IN ULONG_PTR
*StackEnd
)
197 PKTHREAD Thread
= KeGetCurrentThread();
199 /* FIXME: Super native implementation */
201 /* Start with defaults */
202 *StackBegin
= Thread
->StackLimit
;
203 *StackEnd
= (ULONG_PTR
)Thread
->StackBase
;
205 /* Check if we seem to be on the DPC stack */
206 if ((*StackBegin
> Ebp
) || (Ebp
> *StackEnd
))
210 DPRINT1("Stacks: %p %p %p\n", Ebp
, *StackBegin
, *StackEnd
);
217 /* RTL Atom Tables ************************************************************/
220 RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable
)
222 ExInitializeFastMutex(&AtomTable
->FastMutex
);
224 return STATUS_SUCCESS
;
229 RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable
)
235 RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable
)
237 ExAcquireFastMutex(&AtomTable
->FastMutex
);
242 RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable
)
244 ExReleaseFastMutex(&AtomTable
->FastMutex
);
248 RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable
)
250 AtomTable
->ExHandleTable
= ExCreateHandleTable(NULL
);
251 return (AtomTable
->ExHandleTable
!= NULL
);
255 RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable
)
257 if (AtomTable
->ExHandleTable
)
259 ExSweepHandleTable(AtomTable
->ExHandleTable
,
262 ExDestroyHandleTable(AtomTable
->ExHandleTable
, NULL
);
263 AtomTable
->ExHandleTable
= NULL
;
268 RtlpAllocAtomTable(ULONG Size
)
270 PRTL_ATOM_TABLE Table
= ExAllocatePool(NonPagedPool
,
282 RtlpFreeAtomTable(PRTL_ATOM_TABLE AtomTable
)
284 ExFreePool(AtomTable
);
287 PRTL_ATOM_TABLE_ENTRY
288 RtlpAllocAtomTableEntry(ULONG Size
)
290 PRTL_ATOM_TABLE_ENTRY Entry
= ExAllocatePool(NonPagedPool
,
302 RtlpFreeAtomTableEntry(PRTL_ATOM_TABLE_ENTRY Entry
)
308 RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable
, PRTL_ATOM_TABLE_ENTRY Entry
)
310 ExDestroyHandle(AtomTable
->ExHandleTable
,
311 (HANDLE
)((ULONG_PTR
)Entry
->HandleIndex
<< 2),
316 RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable
, PRTL_ATOM_TABLE_ENTRY Entry
)
318 HANDLE_TABLE_ENTRY ExEntry
;
322 ExEntry
.Object
= Entry
;
323 ExEntry
.GrantedAccess
= 0x1; /* FIXME - valid handle */
325 Handle
= ExCreateHandle(AtomTable
->ExHandleTable
,
329 HandleIndex
= (USHORT
)((ULONG_PTR
)Handle
>> 2);
330 /* FIXME - Handle Indexes >= 0xC000 ?! */
331 if ((ULONG_PTR
)HandleIndex
>> 2 < 0xC000)
333 Entry
->HandleIndex
= HandleIndex
;
334 Entry
->Atom
= 0xC000 + HandleIndex
;
339 ExDestroyHandle(AtomTable
->ExHandleTable
,
347 PRTL_ATOM_TABLE_ENTRY
348 RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable
, ULONG Index
)
350 PHANDLE_TABLE_ENTRY ExEntry
;
351 PRTL_ATOM_TABLE_ENTRY Entry
= NULL
;
353 /* NOTE: There's no need to explicitly enter a critical region because it's
354 guaranteed that we're in a critical region right now (as we hold
355 the atom table lock) */
357 ExEntry
= ExMapHandleToPointer(AtomTable
->ExHandleTable
,
358 (HANDLE
)((ULONG_PTR
)Index
<< 2));
361 Entry
= ExEntry
->Object
;
363 ExUnlockHandleTableEntry(AtomTable
->ExHandleTable
,
370 /* FIXME - RtlpCreateUnicodeString is obsolete and should be removed ASAP! */
372 RtlpCreateUnicodeString(
373 IN OUT PUNICODE_STRING UniDest
,
375 IN POOL_TYPE PoolType
)
379 Length
= (wcslen (Source
) + 1) * sizeof(WCHAR
);
380 UniDest
->Buffer
= ExAllocatePoolWithTag(PoolType
, Length
, TAG('U', 'S', 'T', 'R'));
381 if (UniDest
->Buffer
== NULL
)
384 RtlCopyMemory (UniDest
->Buffer
,
388 UniDest
->MaximumLength
= (USHORT
)Length
;
389 UniDest
->Length
= (USHORT
)Length
- sizeof (WCHAR
);
395 * Ldr Resource support code
398 IMAGE_RESOURCE_DIRECTORY
*find_entry_by_name( IMAGE_RESOURCE_DIRECTORY
*dir
,
399 LPCWSTR name
, void *root
,
401 IMAGE_RESOURCE_DIRECTORY
*find_entry_by_id( IMAGE_RESOURCE_DIRECTORY
*dir
,
402 USHORT id
, void *root
, int want_dir
);
403 IMAGE_RESOURCE_DIRECTORY
*find_first_entry( IMAGE_RESOURCE_DIRECTORY
*dir
,
404 void *root
, int want_dir
);
406 /**********************************************************************
409 * Find a resource entry
411 NTSTATUS
find_entry( PVOID BaseAddress
, LDR_RESOURCE_INFO
*info
,
412 ULONG level
, void **ret
, int want_dir
)
416 IMAGE_RESOURCE_DIRECTORY
*resdirptr
;
418 root
= RtlImageDirectoryEntryToData( BaseAddress
, TRUE
, IMAGE_DIRECTORY_ENTRY_RESOURCE
, &size
);
419 if (!root
) return STATUS_RESOURCE_DATA_NOT_FOUND
;
422 if (!level
--) goto done
;
423 if (!(*ret
= find_entry_by_name( resdirptr
, (LPCWSTR
)info
->Type
, root
, want_dir
|| level
)))
424 return STATUS_RESOURCE_TYPE_NOT_FOUND
;
425 if (!level
--) return STATUS_SUCCESS
;
428 if (!(*ret
= find_entry_by_name( resdirptr
, (LPCWSTR
)info
->Name
, root
, want_dir
|| level
)))
429 return STATUS_RESOURCE_NAME_NOT_FOUND
;
430 if (!level
--) return STATUS_SUCCESS
;
431 if (level
) return STATUS_INVALID_PARAMETER
; /* level > 3 */
435 if ((*ret
= find_first_entry( resdirptr
, root
, want_dir
))) return STATUS_SUCCESS
;
437 return STATUS_RESOURCE_DATA_NOT_FOUND
;
441 return STATUS_SUCCESS
;