alcyone/SDK/RTL/guid.c
Quinn Stephens 5c52adf492 [SDK] Big update
Signed-off-by: Quinn Stephens <quinn@osmora.org>
2025-06-11 20:00:34 -04:00

178 lines
3.5 KiB
C

/*++
Copyright (c) 2024-2025, Quinn Stephens.
Provided under the BSD 3-Clause license.
Module Name:
guid.c
Abstract:
Provides RTL GUID routines.
--*/
#include <nt.h>
#include <stdarg.h>
int
ScanHexFormat (
IN PCWSTR Buffer,
IN ULONG MaximumLength,
IN PCWSTR Format,
...
)
/*++
Routine Description:
Parses a formatted hex string.
Arguments:
Buffer - The source string to parse.
MaximumLength - The length of the source string.
Format - The format of the source string.
... - Pointers to data destinations.
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;
}