diff --git a/boot/CMakeLists.txt b/boot/CMakeLists.txt index 8ce56ed64fb..f6275e7f25d 100644 --- a/boot/CMakeLists.txt +++ b/boot/CMakeLists.txt @@ -4,3 +4,4 @@ include(boot_images.cmake) add_subdirectory(bootdata) # add_subdirectory(environ) add_subdirectory(freeldr) +add_subdirectory(rtl) diff --git a/boot/environ/CMakeLists.txt b/boot/environ/CMakeLists.txt index 46d29015499..3874ed3f031 100644 --- a/boot/environ/CMakeLists.txt +++ b/boot/environ/CMakeLists.txt @@ -101,7 +101,7 @@ endif() set_entrypoint(bootmgfw EfiEntry) -target_link_libraries(bootmgfw bootlib cportlib cmlib rtl libcntpr) +target_link_libraries(bootmgfw bootlib cportlib cmlib blrtl libcntpr) # dynamic analysis switches if(STACK_PROTECTOR) @@ -149,7 +149,7 @@ else() set_entrypoint(rosload OslMain) endif() -target_link_libraries(rosload bootlib cportlib cmlib rtl libcntpr) +target_link_libraries(rosload bootlib cportlib cmlib blrtl libcntpr) # dynamic analysis switches if(STACK_PROTECTOR) diff --git a/boot/freeldr/freeldr/CMakeLists.txt b/boot/freeldr/freeldr/CMakeLists.txt index 0827186d090..592f0af85c1 100644 --- a/boot/freeldr/freeldr/CMakeLists.txt +++ b/boot/freeldr/freeldr/CMakeLists.txt @@ -292,7 +292,7 @@ if(ARCH STREQUAL "i386") target_link_libraries(freeldr_pe mini_hal) endif() -target_link_libraries(freeldr_pe freeldr_common cportlib cmlib rtl libcntpr) +target_link_libraries(freeldr_pe freeldr_common cportlib cmlib blrtl libcntpr) # dynamic analysis switches if(STACK_PROTECTOR) diff --git a/boot/rtl/CMakeLists.txt b/boot/rtl/CMakeLists.txt new file mode 100644 index 00000000000..4ed56cd3d6e --- /dev/null +++ b/boot/rtl/CMakeLists.txt @@ -0,0 +1,2 @@ + +include(blrtl.cmake) diff --git a/boot/rtl/blrtl.cmake b/boot/rtl/blrtl.cmake new file mode 100644 index 00000000000..3a51ecb8bc7 --- /dev/null +++ b/boot/rtl/blrtl.cmake @@ -0,0 +1,58 @@ + +add_definitions( + -DNO_RTL_INLINES + -D_BLDR_ + -D_NTSYSTEM_) + +set(NTOS_RTL_SOURCE_DIR "${REACTOS_SOURCE_DIR}/sdk/lib/rtl") +include_directories(${NTOS_RTL_SOURCE_DIR}) + +if (GCC) + # Enable this again. CORE-17637 + add_compile_options(-Wunused-result) +endif() + +list(APPEND SOURCE + # ${NTOS_RTL_SOURCE_DIR}/assert.c ## Requires a local implementation. + ${NTOS_RTL_SOURCE_DIR}/bitmap.c + # ${NTOS_RTL_SOURCE_DIR}/bootdata.c ## Requires a local implementation. + ${NTOS_RTL_SOURCE_DIR}/compress.c + ${NTOS_RTL_SOURCE_DIR}/crc32.c + # ${NTOS_RTL_SOURCE_DIR}/debug.c ## Requires a local implementation. + ${NTOS_RTL_SOURCE_DIR}/image.c + ${NTOS_RTL_SOURCE_DIR}/largeint.c + ## message.c + # ${NTOS_RTL_SOURCE_DIR}/nls.c ## Requires a local implementation. + nlsboot.c + ${NTOS_RTL_SOURCE_DIR}/random.c + ## res.c ## Optional? Needs SEH + # ${NTOS_RTL_SOURCE_DIR}/time.c ## Optional + ${NTOS_RTL_SOURCE_DIR}/unicode.c + ${NTOS_RTL_SOURCE_DIR}/rtl.h) + +if(ARCH STREQUAL "i386") + list(APPEND ASM_SOURCE + ${NTOS_RTL_SOURCE_DIR}/i386/debug_asm.S + ${NTOS_RTL_SOURCE_DIR}/i386/rtlmem.s + ${NTOS_RTL_SOURCE_DIR}/i386/rtlswap.S + ## ${NTOS_RTL_SOURCE_DIR}/i386/res_asm.s + ) +elseif(ARCH STREQUAL "amd64") + list(APPEND ASM_SOURCE + ${NTOS_RTL_SOURCE_DIR}/amd64/debug_asm.S + ${NTOS_RTL_SOURCE_DIR}/amd64/rtlmem.S) + list(APPEND SOURCE + ${NTOS_RTL_SOURCE_DIR}/bitmap64.c + ${NTOS_RTL_SOURCE_DIR}/byteswap.c + ${NTOS_RTL_SOURCE_DIR}/mem.c) +elseif(ARCH STREQUAL "arm") + list(APPEND ASM_SOURCE arm/debug_asm.S) + list(APPEND SOURCE + ${NTOS_RTL_SOURCE_DIR}/byteswap.c + ${NTOS_RTL_SOURCE_DIR}/mem.c) +endif() + +add_asm_files(blrtl_asm ${ASM_SOURCE}) +add_library(blrtl ${SOURCE} ${blrtl_asm}) +add_pch(blrtl ${NTOS_RTL_SOURCE_DIR}/rtl.h SOURCE) +add_dependencies(blrtl psdk asm) diff --git a/boot/rtl/nlsboot.c b/boot/rtl/nlsboot.c new file mode 100644 index 00000000000..917a5922a77 --- /dev/null +++ b/boot/rtl/nlsboot.c @@ -0,0 +1,317 @@ +/* + * PROJECT: FreeLoader + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: "Poor-man" boot-time National Language Support (NLS) functions. + * COPYRIGHT: Copyright 2022 Hermès Bélusca-Maïto + * + * NOTE: This code is used at boot-time when no NLS tables are loaded. + * Adapted from lib/rtl/nls.c + */ + +/* INCLUDES ******************************************************************/ + +#include + +/* GLOBALS *******************************************************************/ + +BOOLEAN NlsMbCodePageTag = FALSE; + +BOOLEAN NlsMbOemCodePageTag = FALSE; +PUSHORT NlsOemToUnicodeTable = NULL; +PCHAR NlsUnicodeToOemTable = NULL; +PUSHORT NlsUnicodeToMbOemTable = NULL; +PUSHORT NlsOemLeadByteInfo = NULL; + +USHORT NlsOemDefaultChar = '\0'; +USHORT NlsUnicodeDefaultChar = 0; + +/* FUNCTIONS *****************************************************************/ + +WCHAR +NTAPI +RtlpDowncaseUnicodeChar( + _In_ WCHAR Source) +{ + USHORT Offset = 0; + + if (Source < L'A') + return Source; + + if (Source <= L'Z') + return Source + (L'a' - L'A'); + +#if 0 + if (Source < 0x80) + return Source; +#endif + + return Source + (SHORT)Offset; +} + +WCHAR +NTAPI +RtlDowncaseUnicodeChar( + _In_ WCHAR Source) +{ + return RtlpDowncaseUnicodeChar(Source); +} + +_Use_decl_annotations_ +NTSTATUS +NTAPI +RtlMultiByteToUnicodeN( + _Out_ PWCH UnicodeString, + _In_ ULONG UnicodeSize, + _Out_opt_ PULONG ResultSize, + _In_ PCCH MbString, + _In_ ULONG MbSize) +{ + ULONG Size = 0; + ULONG i; + + /* single-byte code page */ + if (MbSize > (UnicodeSize / sizeof(WCHAR))) + Size = UnicodeSize / sizeof(WCHAR); + else + Size = MbSize; + + if (ResultSize) + *ResultSize = Size * sizeof(WCHAR); + + for (i = 0; i < Size; i++) + { + /* Trivially zero-extend */ + UnicodeString[i] = (WCHAR)MbString[i]; + } + + return STATUS_SUCCESS; +} + +_Use_decl_annotations_ +NTSTATUS +NTAPI +RtlMultiByteToUnicodeSize( + _Out_ PULONG UnicodeSize, + _In_ PCCH MbString, + _In_ ULONG MbSize) +{ + /* single-byte code page */ + *UnicodeSize = MbSize * sizeof(WCHAR); + + return STATUS_SUCCESS; +} + +_Use_decl_annotations_ +NTSTATUS +NTAPI +RtlUnicodeToMultiByteN( + _Out_ PCHAR MbString, + _In_ ULONG MbSize, + _Out_opt_ PULONG ResultSize, + _In_ PCWCH UnicodeString, + _In_ ULONG UnicodeSize) +{ + ULONG Size = 0; + ULONG i; + + /* single-byte code page */ + Size = (UnicodeSize > (MbSize * sizeof(WCHAR))) + ? MbSize : (UnicodeSize / sizeof(WCHAR)); + + if (ResultSize) + *ResultSize = Size; + + for (i = 0; i < Size; i++) + { + /* Check for characters that cannot be trivially demoted to ANSI */ + if (*((PCHAR)UnicodeString + 1) == 0) + { + *MbString++ = (CHAR)*UnicodeString++; + } + else + { + /* Invalid character, use default */ + *MbString++ = NlsOemDefaultChar; + UnicodeString++; + } + } + + return STATUS_SUCCESS; +} + +_Use_decl_annotations_ +NTSTATUS +NTAPI +RtlUnicodeToMultiByteSize( + _Out_ PULONG MbSize, + _In_ PCWCH UnicodeString, + _In_ ULONG UnicodeSize) +{ + ULONG UnicodeLength = UnicodeSize / sizeof(WCHAR); + + /* single-byte code page */ + *MbSize = UnicodeLength; + + return STATUS_SUCCESS; +} + +WCHAR +NTAPI +RtlpUpcaseUnicodeChar( + _In_ WCHAR Source) +{ + USHORT Offset = 0; + + if (Source < 'a') + return Source; + + if (Source <= 'z') + return (Source - ('a' - 'A')); + + return Source + (SHORT)Offset; +} + +WCHAR +NTAPI +RtlUpcaseUnicodeChar( + _In_ WCHAR Source) +{ + return RtlpUpcaseUnicodeChar(Source); +} + +_Use_decl_annotations_ +NTSTATUS +NTAPI +RtlUpcaseUnicodeToMultiByteN( + _Out_ PCHAR MbString, + _In_ ULONG MbSize, + _Out_opt_ PULONG ResultSize, + _In_ PCWCH UnicodeString, + _In_ ULONG UnicodeSize) +{ + WCHAR UpcaseChar; + ULONG Size = 0; + ULONG i; + + /* single-byte code page */ + if (UnicodeSize > (MbSize * sizeof(WCHAR))) + Size = MbSize; + else + Size = UnicodeSize / sizeof(WCHAR); + + if (ResultSize) + *ResultSize = Size; + + for (i = 0; i < Size; i++) + { + UpcaseChar = RtlpUpcaseUnicodeChar(*UnicodeString); + + /* Check for characters that cannot be trivially demoted to ANSI */ + if (*((PCHAR)&UpcaseChar + 1) == 0) + { + *MbString = (CHAR)UpcaseChar; + } + else + { + /* Invalid character, use default */ + *MbString = NlsOemDefaultChar; + } + + MbString++; + UnicodeString++; + } + + return STATUS_SUCCESS; +} + +CHAR +NTAPI +RtlUpperChar( + _In_ CHAR Source) +{ + /* Check for simple ANSI case */ + if (Source <= 'z') + { + /* Check for simple downcase a-z case */ + if (Source >= 'a') + { + /* Just XOR with the difference */ + return Source ^ ('a' - 'A'); + } + else + { + /* Otherwise return the same char, it's already upcase */ + return Source; + } + } + else + { + /* single-byte code page */ + return (CHAR)RtlpUpcaseUnicodeChar((WCHAR)Source); + } +} + + +/** + * Stubbed OEM helpers that should not be used in the OS boot loader, + * but are necessary for linking with the rest of the RTL unicode.c. + **/ + +_Use_decl_annotations_ +NTSTATUS +NTAPI +RtlUnicodeToOemN( + _Out_ PCHAR OemString, + _In_ ULONG OemSize, + _Out_opt_ PULONG ResultSize, + _In_ PCWCH UnicodeString, + _In_ ULONG UnicodeSize) +{ + if (OemSize) + *OemString = ANSI_NULL; + + if (ResultSize) + *ResultSize = 0; + + return STATUS_NOT_IMPLEMENTED; +} + +_Use_decl_annotations_ +NTSTATUS +NTAPI +RtlOemToUnicodeN( + _Out_ PWCHAR UnicodeString, + _In_ ULONG UnicodeSize, + _Out_opt_ PULONG ResultSize, + _In_ PCCH OemString, + _In_ ULONG OemSize) +{ + if (UnicodeString) + *UnicodeString = UNICODE_NULL; + + if (ResultSize) + *ResultSize = 0; + + return STATUS_NOT_IMPLEMENTED; +} + +_Use_decl_annotations_ +NTSTATUS +NTAPI +RtlUpcaseUnicodeToOemN( + _Out_ PCHAR OemString, + _In_ ULONG OemSize, + _Out_opt_ PULONG ResultSize, + _In_ PCWCH UnicodeString, + _In_ ULONG UnicodeSize) +{ + if (OemSize) + *OemString = ANSI_NULL; + + if (ResultSize) + *ResultSize = 0; + + return STATUS_NOT_IMPLEMENTED; +} + +/* EOF */ diff --git a/sdk/lib/rtl/rtl.h b/sdk/lib/rtl/rtl.h index 7f49ab8de4e..037b2ee2c9b 100644 --- a/sdk/lib/rtl/rtl.h +++ b/sdk/lib/rtl/rtl.h @@ -9,13 +9,15 @@ #ifndef RTL_H #define RTL_H -/* We're a core NT DLL, we don't import syscalls */ +/* We are a core NT DLL, we don't import syscalls */ #define _INC_SWPRINTF_INL_ #undef __MSVCRT__ /* C Headers */ -#include #include +#include + +#ifndef _BLDR_ /* PSDK/NDK Headers */ #define WIN32_NO_STATUS @@ -43,6 +45,12 @@ /* SEH support with PSEH */ #include +#else + +#include + +#endif /* _BLDR_ */ + /* Internal RTL header */ #include "rtlp.h" diff --git a/sdk/lib/rtl/rtlp.h b/sdk/lib/rtl/rtlp.h index be1c7372e96..df2fdf1e0de 100644 --- a/sdk/lib/rtl/rtlp.h +++ b/sdk/lib/rtl/rtlp.h @@ -43,23 +43,31 @@ RtlpSafeCopyMemory( _In_reads_bytes_(Length) CONST VOID UNALIGNED *Source, _In_ SIZE_T Length); +#ifndef _BLDR_ + VOID NTAPI RtlpGetStackLimits(PULONG_PTR LowLimit, PULONG_PTR HighLimit); +#ifdef _M_IX86 + PEXCEPTION_REGISTRATION_RECORD NTAPI RtlpGetExceptionList(VOID); -VOID -NTAPI -RtlpSetHeapParameters(IN PRTL_HEAP_PARAMETERS Parameters); - VOID NTAPI RtlpSetExceptionList(PEXCEPTION_REGISTRATION_RECORD NewExceptionList); +#endif /* _M_IX86 */ + +/* For heap.c */ +VOID +NTAPI +RtlpSetHeapParameters(IN PRTL_HEAP_PARAMETERS Parameters); + +/* For vectoreh.c */ BOOLEAN NTAPI RtlCallVectoredExceptionHandlers( @@ -81,6 +89,8 @@ typedef struct _DISPATCHER_CONTEXT } DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT; #endif +#endif /* !_BLDR_ */ + /* These provide support for sharing code between User and Kernel RTL */ PVOID NTAPI @@ -94,6 +104,8 @@ RtlpFreeMemory( PVOID Mem, ULONG Tag); +#ifndef _BLDR_ + KPROCESSOR_MODE NTAPI RtlpGetMode(VOID); @@ -106,6 +118,7 @@ RtlpCaptureStackLimits( IN ULONG_PTR *StackEnd ); +/* For heap.c and heappage.c */ NTSTATUS NTAPI RtlDeleteHeapLock(IN OUT PHEAP_LOCK Lock); @@ -137,9 +150,13 @@ RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame, IN OUT PULONG_PTR StackLow, IN OUT PULONG_PTR StackHigh); +#endif /* !_BLDR_ */ + #define RtlpAllocateStringMemory RtlpAllocateMemory #define RtlpFreeStringMemory RtlpFreeMemory +#ifndef _BLDR_ + ULONG NTAPI RtlGetTickCount(VOID); @@ -209,18 +226,14 @@ DebugService2( IN ULONG Service ); -/* Tags for the String Allocators */ -#define TAG_USTR 'RTSU' -#define TAG_ASTR 'RTSA' -#define TAG_OSTR 'RTSO' - /* Timer Queue */ - extern HANDLE TimerThreadHandle; NTSTATUS RtlpInitializeTimerThread(VOID); +#endif /* !_BLDR_ */ + /* bitmap64.c */ typedef struct _RTL_BITMAP64 { @@ -234,6 +247,11 @@ typedef struct _RTL_BITMAP_RUN64 ULONG64 NumberOfBits; } RTL_BITMAP_RUN64, *PRTL_BITMAP_RUN64; +/* Tags for the String Allocators */ +#define TAG_USTR 'RTSU' +#define TAG_ASTR 'RTSA' +#define TAG_OSTR 'RTSO' + /* nls.c */ WCHAR NTAPI @@ -243,6 +261,8 @@ WCHAR NTAPI RtlpDowncaseUnicodeChar(IN WCHAR Source); +#ifndef _BLDR_ + /* ReactOS only */ VOID NTAPI @@ -253,5 +273,6 @@ NTAPI RtlpDebugBufferCommit(_Inout_ PRTL_DEBUG_INFORMATION Buffer, _In_ SIZE_T Size); +#endif /* !_BLDR_ */ /* EOF */