diff --git a/sdk/xtdk/rtlfuncs.h b/sdk/xtdk/rtlfuncs.h index e68aa72..ccdf179 100644 --- a/sdk/xtdk/rtlfuncs.h +++ b/sdk/xtdk/rtlfuncs.h @@ -123,6 +123,12 @@ RtlCopyString(IN PCHAR Destination, IN PCSTR Source, IN ULONG Length); +XTCLINK +XTAPI +VOID +RtlCopyUnicodeString(IN OUT PUNICODE_STRING Destination, + IN PCUNICODE_STRING Source); + XTCLINK XTAPI VOID @@ -187,6 +193,18 @@ XTCDECL VOID RtlInitializeListHead(IN PLIST_ENTRY ListHead); +XTCLINK +XTAPI +VOID +RtlInitializeUnicodeString(OUT PUNICODE_STRING Destination, + IN PCWSTR Source); + +XTCLINK +XTAPI +XTSTATUS +RtlInitializeUnicodeStringEx(OUT PUNICODE_STRING Destination, + IN PCWSTR Source); + XTCLINK XTCDECL VOID diff --git a/xtoskrnl/CMakeLists.txt b/xtoskrnl/CMakeLists.txt index 10c4829..95e148a 100644 --- a/xtoskrnl/CMakeLists.txt +++ b/xtoskrnl/CMakeLists.txt @@ -106,6 +106,7 @@ list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc ${XTOSKRNL_SOURCE_DIR}/rtl/string.cc ${XTOSKRNL_SOURCE_DIR}/rtl/time.cc + ${XTOSKRNL_SOURCE_DIR}/rtl/unicode.cc ${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc) # Set module definition SPEC file diff --git a/xtoskrnl/includes/rtl.hh b/xtoskrnl/includes/rtl.hh index 8dae02d..d42a3be 100644 --- a/xtoskrnl/includes/rtl.hh +++ b/xtoskrnl/includes/rtl.hh @@ -27,6 +27,7 @@ #include #include #include +#include #include #endif /* __XTOSKRNL_RTL_HH */ diff --git a/xtoskrnl/includes/rtl/unicode.hh b/xtoskrnl/includes/rtl/unicode.hh new file mode 100644 index 0000000..4dae87a --- /dev/null +++ b/xtoskrnl/includes/rtl/unicode.hh @@ -0,0 +1,29 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/rtl/unicode.hh + * DESCRIPTION: Unicode support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_RTL_UNICODE_HH +#define __XTOSKRNL_RTL_UNICODE_HH + +#include + + +/* Runtime Library */ +namespace RTL +{ + class Unicode + { + public: + STATIC XTAPI VOID CopyString(IN OUT PUNICODE_STRING Destination, + IN PCUNICODE_STRING Source); + STATIC XTAPI XTSTATUS InitializeString(OUT PUNICODE_STRING Destination, + IN PCWSTR Source, + IN BOOLEAN Truncate = FALSE); + }; +} + +#endif /* __XTOSKRNL_RTL_UNICODE_HH */ diff --git a/xtoskrnl/rtl/unicode.cc b/xtoskrnl/rtl/unicode.cc new file mode 100644 index 0000000..0019d9d --- /dev/null +++ b/xtoskrnl/rtl/unicode.cc @@ -0,0 +1,115 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/rtl/unicode.cc + * DESCRIPTION: Unicode support + * DEVELOPERS: Aiken Harris + */ + +#include + + +/** + * Copies a source Unicode string to a destination Unicode string. + * + * @param Destination + * Supplies a pointer to the destination string. + * + * @param Source + * Supplies an optional pointer to the source string. If this parameter is not provided, + * the destination string is effectively emptied. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +RTL::Unicode::CopyString(IN OUT PUNICODE_STRING Destination, + IN PCUNICODE_STRING Source) +{ + ULONG Length; + + /* Check if the source string pointer is valid */ + if(!Source) + { + /* Source is missing, clear the destination string and return */ + Destination->Length = 0; + return; + } + + /* Calculate the length to copy */ + Length = MIN(Source->Length, Destination->MaximumLength); + Destination->Length = Length; + + /* Copy the source string data into the destination buffer */ + RTL::Memory::CopyMemory(Destination->Buffer, Source->Buffer, Length); + + /* Check if there is enough space left in the buffer to NULL-terminate */ + if(Destination->Length < Destination->MaximumLength) + { + /* Append a NULL terminator */ + Destination->Buffer[Length / sizeof(WCHAR)] = (WCHAR)0; + } +} + +/** + * Initializes a Unicode string. + * + * @param Destination + * Supplies a pointer to the UNICODE_STRING structure to be initialized. + * + * @param Source + * Supplies an optional pointer to a NULL-terminated wide character string. + * + * @param Truncate + * Specifies whether to truncate the source string to the maximum allowed length. + * + * @return This routine returns a status code indicating the success or failure of the operation. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +RTL::Unicode::InitializeString(OUT PUNICODE_STRING Destination, + IN PCWSTR Source, + IN BOOLEAN Truncate) +{ + ULONG Size; + + /* Check if the source string pointer is valid */ + if(!Source) + { + /* Source is missing, initialize the destination as empty string */ + Destination->Length = 0; + Destination->MaximumLength = 0; + + /* Return success */ + return STATUS_SUCCESS; + } + + /* Calculate the size of the string in bytes */ + Size = RTL::WideString::WideStringLength(Source, 0) * sizeof(WCHAR); + + /* Check if the size exceeds the maximum allowed */ + if(Size > ((MAXUSHORT & ~1) - sizeof(WCHAR))) + { + /* Check if truncation is not explicitly forced */ + if(!Truncate) + { + /* Return error code */ + return STATUS_NAME_TOO_LONG; + } + + /* Force truncation to the maximum safe length */ + Size = (MAXUSHORT & ~1) - sizeof(WCHAR); + } + + /* Initialize the destination string fields */ + Destination->Buffer = (PWCHAR)Source; + Destination->Length = (USHORT)Size; + Destination->MaximumLength = (USHORT)Size + sizeof(WCHAR); + + /* Return success */ + return STATUS_SUCCESS; +} diff --git a/xtoskrnl/xtoskrnl.spec b/xtoskrnl/xtoskrnl.spec index f5d47ff..6120265 100644 --- a/xtoskrnl/xtoskrnl.spec +++ b/xtoskrnl/xtoskrnl.spec @@ -65,6 +65,7 @@ @ stdcall RtlConvertToLargeIntegerUnsigned32(long) @ stdcall RtlCopyMemory(ptr ptr long) @ stdcall RtlCopyString(ptr ptr long) +@ stdcall RtlCopyUnicodeString(ptr ptr) @ stdcall RtlCopyWideString(ptr ptr long) @ stdcall RtlDivideLargeInteger(long long long ptr) @ stdcall RtlFindClearBits(ptr long long) @@ -75,6 +76,8 @@ @ stdcall RtlFindWideStringInsensitive(wstr wstr) @ stdcall RtlInitializeBitMap(ptr ptr long) @ stdcall RtlInitializeListHead(ptr) +@ stdcall RtlInitializeUnicodeString(ptr wstr) +@ stdcall RtlInitializeUnicodeStringEx(ptr wstr) @ stdcall RtlInsertHeadList(ptr ptr) @ stdcall RtlInsertTailList(ptr ptr) @ stdcall RtlListEmpty(ptr)