229 lines
5.7 KiB
C
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;
|
|||
|
}
|