From ceb86e3cb21443d7d44253868decfe68b5c4a25b Mon Sep 17 00:00:00 2001 From: Kaimakan71 Date: Fri, 9 Aug 2024 08:34:04 -0400 Subject: [PATCH] [SDK:RTL] Add RtlInitUnicodeString() and RtlGUIDFromString() --- SDK/INC/NT/ntrtl.h | 15 ++++ SDK/RTL/guid.c | 174 +++++++++++++++++++++++++++++++++++++++++++++ SDK/RTL/string.c | 63 ++++++++++++++++ premake5.lua | 12 +++- 4 files changed, 263 insertions(+), 1 deletion(-) create mode 100644 SDK/RTL/guid.c create mode 100644 SDK/RTL/string.c diff --git a/SDK/INC/NT/ntrtl.h b/SDK/INC/NT/ntrtl.h index 4e9f5ed..b1ed812 100644 --- a/SDK/INC/NT/ntrtl.h +++ b/SDK/INC/NT/ntrtl.h @@ -17,6 +17,7 @@ Abstract: #define _NTRTL_H #include +#include // // Memory operations. @@ -26,4 +27,18 @@ Abstract: #define RtlFillMemory(Destination, Length, Fill) memset((Destination), (Fill), (Length)) #define RtlZeroMemory(Destination, Length) memset((Destination), 0, (Length)) +VOID +NTAPI +RtlInitUnicodeString ( + OUT PUNICODE_STRING Destination, + IN PCWSTR Source + ); + +NTSTATUS +NTAPI +RtlGUIDFromString ( + IN PUNICODE_STRING String, + OUT GUID *Guid + ); + #endif /* !_NTRTL_H */ diff --git a/SDK/RTL/guid.c b/SDK/RTL/guid.c new file mode 100644 index 0000000..19e36fe --- /dev/null +++ b/SDK/RTL/guid.c @@ -0,0 +1,174 @@ +/*++ + +Copyright (c) 2024, Quinn Stephens. +Provided under the BSD 3-Clause license. + +Module Name: + + guid.c + +Abstract: + + Provides RTL GUID routines. + +--*/ + +#include +#include +#include + +int +ScanHexFormat ( + IN PCWSTR Buffer, + IN ULONG MaximumLength, + IN PCWSTR Format, + ... + ) + +/*++ + +Routine Description: + + Turns a text representation of a GUID into the binary format. + +Arguments: + + String - A GUID string in the format {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. + + Guid - The GUID structure which is to recieve the data. + +Return Value: + + Number of parameters scanned if successful. + -1 if scanning fails. + +--*/ + +{ + va_list Args; + int FormatCount = 0; + int Width, Long; + ULONG Number; + PVOID Dest; + + va_start(Args, Format); + while (*Format != '\0') { + // + // Ignore some characters. + // + if (*Format != '%' || *(Format + 1) == '%') { + if (!MaximumLength || *Buffer != *Format) { + return -1; + } + + Buffer++; + MaximumLength--; + Format++; + continue; + } + + // + // Find format kind. + // + Format++; + Width = 0; + Long = 0; + while (*Format != 'X' && *Format != 'x') { + if (*Format >= '0' && *Format <= '9') { + Width = Width * 10 + *Format - '0'; + } else if (*Format == 'l') { + Long++; + } + Format++; + } + + // + // Calculate number value. + // + Format++; + Number = 0; + while (Width--) { + if (!MaximumLength) { + return -1; + } + + if (*Buffer >= '0' && *Buffer <= '9') { + Number += *Buffer - '0'; + } else if (*Buffer >= 'a' && *Buffer <= 'f') { + Number += *Buffer - 'a' + 0xa; + } else if (*Buffer >= 'A' && *Buffer <= 'F') { + Number += *Buffer - 'A' + 0xA; + } else { + return -1; + } + + Buffer++; + MaximumLength--; + } + + // + // Store number in destination. + // + Dest = va_arg(Args, PVOID); + if (Long) { + *(PULONG)Dest = Number; + } else { + *(PUSHORT)Dest = (USHORT)Number; + } + + FormatCount++; + } + va_end(Args); + + return (MaximumLength && *Buffer) ? -1:FormatCount; +} + +NTSTATUS +NTAPI +RtlGUIDFromString ( + IN PUNICODE_STRING String, + OUT GUID *Guid + ) + +/*++ + +Routine Description: + + Turns a text representation of a GUID into the binary format. + +Arguments: + + String - A GUID string in the format {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. + + Guid - The GUID structure which is to recieve the data. + +Return Value: + + STATUS_SUCCESS if successful. + STATUS_INVALID_PARAMETER if the string is invalid. + +--*/ + +{ + USHORT Data4[8]; + + // + // Convert string to GUID data. + // + if (ScanHexFormat( + String->Buffer, String->Length / sizeof(WCHAR), + L"{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + &Guid->Data1, &Guid->Data2, &Guid->Data3, &Data4[0], &Data4[1], &Data4[2], &Data4[3], &Data4[4], &Data4[5], &Data4[6], &Data4[7] + ) == -1) { + return STATUS_INVALID_PARAMETER; + } + + // + // Convert USHORTs to UCHARs. + // + for (int Index = 0; Index < 8; Index++) { + Guid->Data4[Index] = (UCHAR)Data4[Index]; + } + + return STATUS_SUCCESS; +} diff --git a/SDK/RTL/string.c b/SDK/RTL/string.c new file mode 100644 index 0000000..e24a8ff --- /dev/null +++ b/SDK/RTL/string.c @@ -0,0 +1,63 @@ +/*++ + +Copyright (c) 2024, Quinn Stephens. +Provided under the BSD 3-Clause license. + +Module Name: + + string.c + +Abstract: + + Provides RTL string routines. + +--*/ + +#include +#include + +VOID +NTAPI +RtlInitUnicodeString ( + OUT PUNICODE_STRING Destination, + IN PCWSTR Source + ) + +/*++ + +Routine Description: + + Initializes a unicode string structure with an existing string, + which may be NULL to initialize an empty unicode string structure. + +Arguments: + + Destination - A pointer to the unicode string structure. + + Source - Optionally, a pointer to a null-terminated string to initialize + the unicode string structure with. + +Return Value: + + None. + +--*/ + +{ + ULONG Length; + + Destination->Buffer = (PWSTR)Source; + if (Source == NULL) { + Destination->Length = 0; + Destination->MaximumLength = 0; + return; + } + + Length = wcslen(Source) * sizeof(WCHAR); + if (Length >= MAX_USTRING) { + Length = MAX_USTRING - sizeof(UNICODE_NULL); + } + + Destination->Length = (USHORT)Length; + Destination->MaximumLength = (USHORT)(Length + sizeof(UNICODE_NULL)); +} diff --git a/premake5.lua b/premake5.lua index 3e53787..e73ee3e 100644 --- a/premake5.lua +++ b/premake5.lua @@ -31,11 +31,21 @@ project("CRT") targetname("crt") files({ "SDK/INC/CRT/**.h", "SDK/CRT/**.c" }) +project("RTL") + kind("StaticLib") + location("SDK/RTL") + + includedirs({ "SDK/INC/CRT", "SDK/INC/NT" }) + objdir("BUILD/SDK/RTL") + targetdir("BUILD/SDK") + targetname("rtl") + files({ "SDK/INC/NT/ntrtl.h", "SDK/RTL/**.c" }) + --[[ project("BOOT") kind("ConsoleApp") - includedirs({ "BOOT/ENVIRON/INC", "SDK/INC/CRT" }) + includedirs({ "BOOT/ENVIRON/INC", "SDK/INC" }) objdir("BUILD/BOOT") targetdir("BUILD/BOOT") files({ "BOOT/ENVIRON/INC/**.h", "BOOT/ENVIRON/**.c" })