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(VOID
)
24 /* This check is meaningless in kernel-mode */
37 RtlpAllocateMemory(UINT Bytes
,
40 return ExAllocatePoolWithTag(PagedPool
,
48 RtlpFreeMemory(PVOID Mem
,
51 ExFreePoolWithTag(Mem
,
59 RtlAcquirePebLock(VOID
)
68 RtlReleasePebLock(VOID
)
75 LdrShutdownThread(VOID
)
77 return STATUS_SUCCESS
;
85 return ((PEPROCESS
)(KeGetCurrentThread()->ApcState
.Process
))->Peb
;
91 PRTL_CRITICAL_SECTION CriticalSection
)
93 return STATUS_SUCCESS
;
99 PRTL_CRITICAL_SECTION CriticalSection
)
101 ExAcquireFastMutex((PFAST_MUTEX
) CriticalSection
);
102 return STATUS_SUCCESS
;
107 RtlInitializeHeapLock(
108 PRTL_CRITICAL_SECTION CriticalSection
)
110 ExInitializeFastMutex((PFAST_MUTEX
)CriticalSection
);
111 return STATUS_SUCCESS
;
117 PRTL_CRITICAL_SECTION CriticalSection
)
119 ExReleaseFastMutex((PFAST_MUTEX
) CriticalSection
);
120 return STATUS_SUCCESS
;
125 CHECK_PAGED_CODE_RTL(char *file
, int line
)
127 if(KeGetCurrentIrql() > APC_LEVEL
)
129 DbgPrint("%s:%i: Pagable code called at IRQL > APC_LEVEL (%d)\n", file
, line
, KeGetCurrentIrql());
137 RtlpCheckLogException(IN PEXCEPTION_RECORD ExceptionRecord
,
138 IN PCONTEXT ContextRecord
,
139 IN PVOID ContextData
,
142 /* Check the global flag */
143 if (NtGlobalFlag
& FLG_ENABLE_EXCEPTION_LOGGING
)
145 /* FIXME: Log this exception */
151 RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame
,
152 IN ULONG_PTR RegistrationFrameEnd
,
153 IN OUT PULONG_PTR StackLow
,
154 IN OUT PULONG_PTR StackHigh
)
159 /* Check if we are at DISPATCH or higher */
160 if (KeGetCurrentIrql() >= DISPATCH_LEVEL
)
162 /* Get the PRCB and DPC Stack */
163 Prcb
= KeGetCurrentPrcb();
164 DpcStack
= (ULONG_PTR
)Prcb
->DpcStack
;
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))
171 /* Update the limits to the DPC Stack's */
172 *StackHigh
= DpcStack
;
173 *StackLow
= DpcStack
- 4096;
178 /* Not in DPC stack */
182 /* RTL Atom Tables ************************************************************/
185 RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable
)
187 ExInitializeFastMutex(&AtomTable
->FastMutex
);
189 return STATUS_SUCCESS
;
194 RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable
)
200 RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable
)
202 ExAcquireFastMutex(&AtomTable
->FastMutex
);
207 RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable
)
209 ExReleaseFastMutex(&AtomTable
->FastMutex
);
213 RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable
)
215 AtomTable
->ExHandleTable
= ExCreateHandleTable(NULL
);
216 return (AtomTable
->ExHandleTable
!= NULL
);
220 AtomDeleteHandleCallback(PHANDLE_TABLE HandleTable
,
229 RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable
)
231 if (AtomTable
->ExHandleTable
)
233 ExDestroyHandleTable(AtomTable
->ExHandleTable
,
234 AtomDeleteHandleCallback
,
236 AtomTable
->ExHandleTable
= NULL
;
241 RtlpAllocAtomTable(ULONG Size
)
243 PRTL_ATOM_TABLE Table
= ExAllocatePool(NonPagedPool
,
255 RtlpFreeAtomTable(PRTL_ATOM_TABLE AtomTable
)
257 ExFreePool(AtomTable
);
260 PRTL_ATOM_TABLE_ENTRY
261 RtlpAllocAtomTableEntry(ULONG Size
)
263 PRTL_ATOM_TABLE_ENTRY Entry
= ExAllocatePool(NonPagedPool
,
275 RtlpFreeAtomTableEntry(PRTL_ATOM_TABLE_ENTRY Entry
)
281 RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable
, PRTL_ATOM_TABLE_ENTRY Entry
)
283 ExDestroyHandle(AtomTable
->ExHandleTable
,
284 (HANDLE
)((ULONG_PTR
)Entry
->HandleIndex
<< 2));
288 RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable
, PRTL_ATOM_TABLE_ENTRY Entry
)
290 HANDLE_TABLE_ENTRY ExEntry
;
294 ExEntry
.u1
.Object
= Entry
;
295 ExEntry
.u2
.GrantedAccess
= 0x1; /* FIXME - valid handle */
297 Handle
= ExCreateHandle(AtomTable
->ExHandleTable
,
301 HandleIndex
= (USHORT
)((ULONG_PTR
)Handle
>> 2);
302 /* FIXME - Handle Indexes >= 0xC000 ?! */
303 if ((ULONG_PTR
)HandleIndex
>> 2 < 0xC000)
305 Entry
->HandleIndex
= HandleIndex
;
306 Entry
->Atom
= 0xC000 + HandleIndex
;
311 ExDestroyHandle(AtomTable
->ExHandleTable
,
318 PRTL_ATOM_TABLE_ENTRY
319 RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable
, ULONG Index
)
321 PHANDLE_TABLE_ENTRY ExEntry
;
322 PRTL_ATOM_TABLE_ENTRY Entry
= NULL
;
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) */
328 ExEntry
= ExMapHandleToPointer(AtomTable
->ExHandleTable
,
329 (HANDLE
)((ULONG_PTR
)Index
<< 2));
332 Entry
= ExEntry
->u1
.Object
;
334 ExUnlockHandleTableEntry(AtomTable
->ExHandleTable
,
341 /* FIXME - RtlpCreateUnicodeString is obsolete and should be removed ASAP! */
343 RtlpCreateUnicodeString(
344 IN OUT PUNICODE_STRING UniDest
,
346 IN POOL_TYPE PoolType
)
350 Length
= (wcslen (Source
) + 1) * sizeof(WCHAR
);
351 UniDest
->Buffer
= ExAllocatePoolWithTag(PoolType
, Length
, TAG('U', 'S', 'T', 'R'));
352 if (UniDest
->Buffer
== NULL
)
355 RtlCopyMemory (UniDest
->Buffer
,
359 UniDest
->MaximumLength
= Length
;
360 UniDest
->Length
= Length
- sizeof (WCHAR
);