[SDK:RTL] Add RtlInitUnicodeString() and RtlGUIDFromString()

This commit is contained in:
Quinn Stephens 2024-08-09 08:34:04 -04:00
parent 0998d5c417
commit ceb86e3cb2
4 changed files with 263 additions and 1 deletions

View File

@ -17,6 +17,7 @@ Abstract:
#define _NTRTL_H
#include <string.h>
#include <ntdef.h>
//
// 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 */

174
SDK/RTL/guid.c Normal file
View File

@ -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 <ntrtl.h>
#include <ntstatus.h>
#include <stdarg.h>
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;
}

63
SDK/RTL/string.c Normal file
View File

@ -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 <ntrtl.h>
#include <wchar.h>
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));
}

View File

@ -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" })