Windows2000/private/ntos/rtl/guid.c
2020-09-30 17:12:32 +02:00

229 lines
5.7 KiB
C

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
guid.c
Abstract:
This Module implements the guid manipulation functions.
Author:
George Shaw (GShaw) 9-Oct-1996
Environment:
Pure Runtime Library Routine
Revision History:
--*/
#include "nt.h"
#include "ntrtlp.h"
#if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
static
int
__cdecl
ScanHexFormat(
IN const WCHAR* Buffer,
IN ULONG MaximumLength,
IN const WCHAR* Format,
...);
#pragma alloc_text(PAGE, RtlStringFromGUID)
#pragma alloc_text(PAGE, ScanHexFormat)
#pragma alloc_text(PAGE, RtlGUIDFromString)
#endif // ALLOC_PRAGMA && NTOS_KERNEL_RUNTIME
extern const WCHAR GuidFormat[];
#define GUID_STRING_SIZE 38
NTSYSAPI
NTSTATUS
NTAPI
RtlStringFromGUID(
IN REFGUID Guid,
OUT PUNICODE_STRING GuidString
)
/*++
Routine Description:
Constructs the standard string version of a GUID, in the form:
"{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}".
Arguments:
Guid -
Contains the GUID to translate.
GuidString -
Returns a string that represents the textual format of the GUID.
Caller must call RtlFreeUnicodeString to free the buffer when done with
it.
Return Value:
NTSTATUS - Returns STATUS_SUCCESS if the user string was succesfully
initialized.
--*/
{
RTL_PAGED_CODE();
GuidString->Length = GUID_STRING_SIZE * sizeof(WCHAR);
GuidString->MaximumLength = GuidString->Length + sizeof(UNICODE_NULL);
if (!(GuidString->Buffer = RtlAllocateStringRoutine(GuidString->MaximumLength))) {
return STATUS_NO_MEMORY;
}
swprintf(GuidString->Buffer, GuidFormat, Guid->Data1, Guid->Data2, Guid->Data3, Guid->Data4[0], Guid->Data4[1], Guid->Data4[2], Guid->Data4[3], Guid->Data4[4], Guid->Data4[5], Guid->Data4[6], Guid->Data4[7]);
return STATUS_SUCCESS;
}
static
int
__cdecl
ScanHexFormat(
IN const WCHAR* Buffer,
IN ULONG MaximumLength,
IN const WCHAR* Format,
...)
/*++
Routine Description:
Scans a source Buffer and places values from that buffer into the parameters
as specified by Format.
Arguments:
Buffer -
Contains the source buffer which is to be scanned.
MaximumLength -
Contains the maximum length in characters for which Buffer is searched.
This implies that Buffer need not be UNICODE_NULL terminated.
Format -
Contains the format string which defines both the acceptable string format
contained in Buffer, and the variable parameters which follow.
Return Value:
Returns the number of parameters filled if the end of the Buffer is reached,
else -1 on an error.
--*/
{
va_list ArgList;
int FormatItems;
va_start(ArgList, Format);
for (FormatItems = 0;;) {
switch (*Format) {
case 0:
return (MaximumLength && *Buffer) ? -1 : FormatItems;
case '%':
Format++;
if (*Format != '%') {
ULONG Number;
int Width;
int Long;
PVOID Pointer;
for (Long = 0, Width = 0;; Format++) {
if ((*Format >= '0') && (*Format <= '9')) {
Width = Width * 10 + *Format - '0';
} else if (*Format == 'l') {
Long++;
} else if ((*Format == 'X') || (*Format == 'x')) {
break;
}
}
Format++;
for (Number = 0; Width--; Buffer++, MaximumLength--) {
if (!MaximumLength)
return -1;
Number *= 16;
if ((*Buffer >= '0') && (*Buffer <= '9')) {
Number += (*Buffer - '0');
} else if ((*Buffer >= 'a') && (*Buffer <= 'f')) {
Number += (*Buffer - 'a' + 10);
} else if ((*Buffer >= 'A') && (*Buffer <= 'F')) {
Number += (*Buffer - 'A' + 10);
} else {
return -1;
}
}
Pointer = va_arg(ArgList, PVOID);
if (Long) {
*(PULONG)Pointer = Number;
} else {
*(PUSHORT)Pointer = (USHORT)Number;
}
FormatItems++;
break;
}
/* no break */
default:
if (!MaximumLength || (*Buffer != *Format)) {
return -1;
}
Buffer++;
MaximumLength--;
Format++;
break;
}
}
}
NTSYSAPI
NTSTATUS
NTAPI
RtlGUIDFromString(
IN PUNICODE_STRING GuidString,
OUT GUID* Guid
)
/*++
Routine Description:
Retrieves a the binary format of a textual GUID presented in the standard
string version of a GUID: "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}".
Arguments:
GuidString -
Place from which to retrieve the textual form of the GUID.
Guid -
Place in which to put the binary form of the GUID.
Return Value:
Returns STATUS_SUCCESS if the buffer contained a valid GUID, else
STATUS_INVALID_PARAMETER if the string was invalid.
--*/
{
USHORT Data4[8];
int Count;
RTL_PAGED_CODE();
if (ScanHexFormat(GuidString->Buffer, GuidString->Length / sizeof(WCHAR), GuidFormat, &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;
}
for (Count = 0; Count < sizeof(Data4)/sizeof(Data4[0]); Count++) {
Guid->Data4[Count] = (UCHAR)Data4[Count];
}
return STATUS_SUCCESS;
}