https://git.reactos.org/?p=reactos.git;a=commitdiff;h=24cb57fdead78f88236d2…
commit 24cb57fdead78f88236d2e92e4293c4fc6c9c48f
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon Mar 21 21:06:52 2022 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Thu Apr 7 03:19:09 2022 +0200
[BOOT][SDK:RTL] Compile a reduced RTL library for FreeLdr / NT bootloader...
... as it should have always been done (and must be done for NTDLL
and NTOS kernel as well). This allows using the RTL with the correct
definitions and the reduced functionality available at boot-time.
+ Make the RTL main header compatible.
In addition, this will permit re-using existing code that already
uses the RTL (mostly string conversions).
See commits 427c90af3 (r36761) and b46e8cc18 (r36980) for some
background.
---
boot/CMakeLists.txt | 1 +
boot/environ/CMakeLists.txt | 4 +-
boot/freeldr/freeldr/CMakeLists.txt | 2 +-
boot/rtl/CMakeLists.txt | 2 +
boot/rtl/blrtl.cmake | 58 +++++++
boot/rtl/nlsboot.c | 317 ++++++++++++++++++++++++++++++++++++
sdk/lib/rtl/rtl.h | 12 +-
sdk/lib/rtl/rtlp.h | 37 ++++-
8 files changed, 420 insertions(+), 13 deletions(-)
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 <rtl.h>
+
+/* 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 <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef _BLDR_
/* PSDK/NDK Headers */
#define WIN32_NO_STATUS
@@ -43,6 +45,12 @@
/* SEH support with PSEH */
#include <pseh/pseh2.h>
+#else
+
+#include <ndk/rtlfuncs.h>
+
+#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);
+RtlpSetExceptionList(PEXCEPTION_REGISTRATION_RECORD NewExceptionList);
+
+#endif /* _M_IX86 */
+/* For heap.c */
VOID
NTAPI
-RtlpSetExceptionList(PEXCEPTION_REGISTRATION_RECORD NewExceptionList);
+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 */