2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NT User-Mode DLL
4 * FILE: lib/ntdll/rtl/libsup.c
5 * PURPOSE: RTL Support Routines
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
10 /* INCLUDES *****************************************************************/
16 /* FUNCTIONS ***************************************************************/
20 RtlpCheckForActiveDebugger(BOOLEAN Type
)
22 return (NtCurrentPeb()->BeingDebugged
);
27 RtlpSetInDbgPrint(IN BOOLEAN NewValue
)
29 /* If we're setting it to false, do it and return */
30 if (NewValue
== FALSE
)
32 NtCurrentTeb()->InDbgPrint
= FALSE
;
36 /* Setting to true; check if it's not already */
37 if (NtCurrentTeb()->InDbgPrint
) return TRUE
;
39 /* Set it and return */
40 NtCurrentTeb()->InDbgPrint
= TRUE
;
55 return NtCurrentPeb();
62 RtlAcquirePebLock(VOID
)
64 PPEB Peb
= NtCurrentPeb ();
65 Peb
->FastPebLockRoutine (Peb
->FastPebLock
);
72 RtlReleasePebLock(VOID
)
74 PPEB Peb
= NtCurrentPeb ();
75 Peb
->FastPebUnlockRoutine (Peb
->FastPebLock
);
83 RtlGetNtGlobalFlags(VOID
)
85 PPEB pPeb
= NtCurrentPeb();
86 return pPeb
->NtGlobalFlag
;
92 PRTL_CRITICAL_SECTION CriticalSection
)
94 return RtlDeleteCriticalSection(CriticalSection
);
100 PRTL_CRITICAL_SECTION CriticalSection
)
102 return RtlEnterCriticalSection(CriticalSection
);
107 RtlInitializeHeapLock(
108 PRTL_CRITICAL_SECTION CriticalSection
)
110 return RtlInitializeCriticalSection(CriticalSection
);
116 PRTL_CRITICAL_SECTION CriticalSection
)
118 return RtlLeaveCriticalSection(CriticalSection
);
123 RtlpAllocateMemory(UINT Bytes
,
126 UNREFERENCED_PARAMETER(Tag
);
128 return RtlAllocateHeap(RtlGetProcessHeap(),
136 RtlpFreeMemory(PVOID Mem
,
139 UNREFERENCED_PARAMETER(Tag
);
141 RtlFreeHeap(RtlGetProcessHeap(),
149 CHECK_PAGED_CODE_RTL(char *file
, int line
)
151 /* meaningless in user mode */
157 RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame
,
158 IN ULONG_PTR RegistrationFrameEnd
,
159 IN OUT PULONG_PTR StackLow
,
160 IN OUT PULONG_PTR StackHigh
)
162 /* There's no such thing as a DPC stack in user-mode */
168 RtlpCheckLogException(IN PEXCEPTION_RECORD ExceptionRecord
,
169 IN PCONTEXT ContextRecord
,
170 IN PVOID ContextData
,
173 /* Exception logging is not done in user-mode */
176 /* RTL Atom Tables ************************************************************/
178 typedef struct _RTL_ATOM_HANDLE
180 RTL_HANDLE_TABLE_ENTRY Handle
;
181 PRTL_ATOM_TABLE_ENTRY AtomEntry
;
182 } RTL_ATOM_HANDLE
, *PRTL_ATOM_HANDLE
;
185 RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable
)
187 RtlInitializeCriticalSection(&AtomTable
->CriticalSection
);
188 return STATUS_SUCCESS
;
193 RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable
)
195 RtlDeleteCriticalSection(&AtomTable
->CriticalSection
);
200 RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable
)
202 RtlEnterCriticalSection(&AtomTable
->CriticalSection
);
208 RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable
)
210 RtlLeaveCriticalSection(&AtomTable
->CriticalSection
);
214 /* handle functions */
217 RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable
)
219 RtlInitializeHandleTable(0xCFFF,
220 sizeof(RTL_ATOM_HANDLE
),
221 &AtomTable
->RtlHandleTable
);
227 RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable
)
229 RtlDestroyHandleTable(&AtomTable
->RtlHandleTable
);
233 RtlpAllocAtomTable(ULONG Size
)
235 return (PRTL_ATOM_TABLE
)RtlAllocateHeap(RtlGetProcessHeap(),
241 RtlpFreeAtomTable(PRTL_ATOM_TABLE AtomTable
)
243 RtlFreeHeap(RtlGetProcessHeap(),
248 PRTL_ATOM_TABLE_ENTRY
249 RtlpAllocAtomTableEntry(ULONG Size
)
251 return (PRTL_ATOM_TABLE_ENTRY
)RtlAllocateHeap(RtlGetProcessHeap(),
257 RtlpFreeAtomTableEntry(PRTL_ATOM_TABLE_ENTRY Entry
)
259 RtlFreeHeap(RtlGetProcessHeap(),
265 RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable
, PRTL_ATOM_TABLE_ENTRY Entry
)
267 PRTL_HANDLE_TABLE_ENTRY RtlHandleEntry
;
269 if (RtlIsValidIndexHandle(&AtomTable
->RtlHandleTable
,
270 (ULONG
)Entry
->HandleIndex
,
273 RtlFreeHandle(&AtomTable
->RtlHandleTable
,
279 RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable
, PRTL_ATOM_TABLE_ENTRY Entry
)
282 PRTL_HANDLE_TABLE_ENTRY RtlHandle
;
284 RtlHandle
= RtlAllocateHandle(&AtomTable
->RtlHandleTable
,
286 if (RtlHandle
!= NULL
)
288 PRTL_ATOM_HANDLE AtomHandle
= (PRTL_ATOM_HANDLE
)RtlHandle
;
290 /* FIXME - Handle Indexes >= 0xC000 ?! */
291 if (HandleIndex
< 0xC000)
293 Entry
->HandleIndex
= (USHORT
)HandleIndex
;
294 Entry
->Atom
= 0xC000 + (USHORT
)HandleIndex
;
296 AtomHandle
->AtomEntry
= Entry
;
297 AtomHandle
->Handle
.Flags
= RTL_HANDLE_VALID
;
303 /* set the valid flag, otherwise RtlFreeHandle will fail! */
304 AtomHandle
->Handle
.Flags
= RTL_HANDLE_VALID
;
306 RtlFreeHandle(&AtomTable
->RtlHandleTable
,
314 PRTL_ATOM_TABLE_ENTRY
315 RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable
, ULONG Index
)
317 PRTL_HANDLE_TABLE_ENTRY RtlHandle
;
319 if (RtlIsValidIndexHandle(&AtomTable
->RtlHandleTable
,
323 PRTL_ATOM_HANDLE AtomHandle
= (PRTL_ATOM_HANDLE
)RtlHandle
;
325 return AtomHandle
->AtomEntry
;
333 * Ldr Resource support code
336 IMAGE_RESOURCE_DIRECTORY
*find_entry_by_name( IMAGE_RESOURCE_DIRECTORY
*dir
,
337 LPCWSTR name
, void *root
,
339 IMAGE_RESOURCE_DIRECTORY
*find_entry_by_id( IMAGE_RESOURCE_DIRECTORY
*dir
,
340 WORD id
, void *root
, int want_dir
);
341 IMAGE_RESOURCE_DIRECTORY
*find_first_entry( IMAGE_RESOURCE_DIRECTORY
*dir
,
342 void *root
, int want_dir
);
343 int push_language( USHORT
*list
, ULONG pos
, WORD lang
);
345 /**********************************************************************
348 * Find a resource entry
350 NTSTATUS
find_entry( PVOID BaseAddress
, LDR_RESOURCE_INFO
*info
,
351 ULONG level
, void **ret
, int want_dir
)
355 IMAGE_RESOURCE_DIRECTORY
*resdirptr
;
356 USHORT list
[9]; /* list of languages to try */
358 LCID user_lcid
, system_lcid
;
360 root
= RtlImageDirectoryEntryToData( BaseAddress
, TRUE
, IMAGE_DIRECTORY_ENTRY_RESOURCE
, &size
);
361 if (!root
) return STATUS_RESOURCE_DATA_NOT_FOUND
;
364 if (!level
--) goto done
;
365 if (!(*ret
= find_entry_by_name( resdirptr
, (LPCWSTR
)info
->Type
, root
, want_dir
|| level
)))
366 return STATUS_RESOURCE_TYPE_NOT_FOUND
;
367 if (!level
--) return STATUS_SUCCESS
;
370 if (!(*ret
= find_entry_by_name( resdirptr
, (LPCWSTR
)info
->Name
, root
, want_dir
|| level
)))
371 return STATUS_RESOURCE_NAME_NOT_FOUND
;
372 if (!level
--) return STATUS_SUCCESS
;
373 if (level
) return STATUS_INVALID_PARAMETER
; /* level > 3 */
375 /* 1. specified language */
376 pos
= push_language( list
, pos
, info
->Language
);
378 /* 2. specified language with neutral sublanguage */
379 pos
= push_language( list
, pos
, MAKELANGID( PRIMARYLANGID(info
->Language
), SUBLANG_NEUTRAL
) );
381 /* 3. neutral language with neutral sublanguage */
382 pos
= push_language( list
, pos
, MAKELANGID( LANG_NEUTRAL
, SUBLANG_NEUTRAL
) );
384 /* if no explicitly specified language, try some defaults */
385 if (PRIMARYLANGID(info
->Language
) == LANG_NEUTRAL
)
387 /* user defaults, unless SYS_DEFAULT sublanguage specified */
388 if (SUBLANGID(info
->Language
) != SUBLANG_SYS_DEFAULT
)
390 /* 4. current thread locale language */
391 pos
= push_language( list
, pos
, LANGIDFROMLCID(NtCurrentTeb()->CurrentLocale
) );
393 if (NT_SUCCESS(NtQueryDefaultLocale(TRUE
, &user_lcid
)))
395 /* 5. user locale language */
396 pos
= push_language( list
, pos
, LANGIDFROMLCID(user_lcid
) );
398 /* 6. user locale language with neutral sublanguage */
399 pos
= push_language( list
, pos
, MAKELANGID( PRIMARYLANGID(user_lcid
), SUBLANG_NEUTRAL
) );
403 /* now system defaults */
405 if (NT_SUCCESS(NtQueryDefaultLocale(FALSE
, &system_lcid
)))
407 /* 7. system locale language */
408 pos
= push_language( list
, pos
, LANGIDFROMLCID( system_lcid
) );
410 /* 8. system locale language with neutral sublanguage */
411 pos
= push_language( list
, pos
, MAKELANGID( PRIMARYLANGID(system_lcid
), SUBLANG_NEUTRAL
) );
415 pos
= push_language( list
, pos
, MAKELANGID( LANG_ENGLISH
, SUBLANG_DEFAULT
) );
419 for (i
= 0; i
< pos
; i
++)
420 if ((*ret
= find_entry_by_id( resdirptr
, list
[i
], root
, want_dir
))) return STATUS_SUCCESS
;
422 /* if no explicitly specified language, return the first entry */
423 if (PRIMARYLANGID(info
->Language
) == LANG_NEUTRAL
)
425 if ((*ret
= find_first_entry( resdirptr
, root
, want_dir
))) return STATUS_SUCCESS
;
427 return STATUS_RESOURCE_LANG_NOT_FOUND
;
431 return STATUS_SUCCESS
;