Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
5.7 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. guid.c
  5. Abstract:
  6. This Module implements the guid manipulation functions.
  7. Author:
  8. George Shaw (GShaw) 9-Oct-1996
  9. Environment:
  10. Pure Runtime Library Routine
  11. Revision History:
  12. --*/
  13. #include "nt.h"
  14. #include "ntrtlp.h"
  15. #if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
  16. static
  17. int
  18. __cdecl
  19. ScanHexFormat(
  20. IN const WCHAR* Buffer,
  21. IN ULONG MaximumLength,
  22. IN const WCHAR* Format,
  23. ...);
  24. #pragma alloc_text(PAGE, RtlStringFromGUID)
  25. #pragma alloc_text(PAGE, ScanHexFormat)
  26. #pragma alloc_text(PAGE, RtlGUIDFromString)
  27. #endif // ALLOC_PRAGMA && NTOS_KERNEL_RUNTIME
  28. extern const WCHAR GuidFormat[];
  29. #define GUID_STRING_SIZE 38
  30. NTSYSAPI
  31. NTSTATUS
  32. NTAPI
  33. RtlStringFromGUID(
  34. IN REFGUID Guid,
  35. OUT PUNICODE_STRING GuidString
  36. )
  37. /*++
  38. Routine Description:
  39. Constructs the standard string version of a GUID, in the form:
  40. "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}".
  41. Arguments:
  42. Guid -
  43. Contains the GUID to translate.
  44. GuidString -
  45. Returns a string that represents the textual format of the GUID.
  46. Caller must call RtlFreeUnicodeString to free the buffer when done with
  47. it.
  48. Return Value:
  49. NTSTATUS - Returns STATUS_SUCCESS if the user string was succesfully
  50. initialized.
  51. --*/
  52. {
  53. RTL_PAGED_CODE();
  54. GuidString->Length = GUID_STRING_SIZE * sizeof(WCHAR);
  55. GuidString->MaximumLength = GuidString->Length + sizeof(UNICODE_NULL);
  56. if (!(GuidString->Buffer = RtlAllocateStringRoutine(GuidString->MaximumLength))) {
  57. return STATUS_NO_MEMORY;
  58. }
  59. 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]);
  60. return STATUS_SUCCESS;
  61. }
  62. static
  63. int
  64. __cdecl
  65. ScanHexFormat(
  66. IN const WCHAR* Buffer,
  67. IN ULONG MaximumLength,
  68. IN const WCHAR* Format,
  69. ...)
  70. /*++
  71. Routine Description:
  72. Scans a source Buffer and places values from that buffer into the parameters
  73. as specified by Format.
  74. Arguments:
  75. Buffer -
  76. Contains the source buffer which is to be scanned.
  77. MaximumLength -
  78. Contains the maximum length in characters for which Buffer is searched.
  79. This implies that Buffer need not be UNICODE_NULL terminated.
  80. Format -
  81. Contains the format string which defines both the acceptable string format
  82. contained in Buffer, and the variable parameters which follow.
  83. Return Value:
  84. Returns the number of parameters filled if the end of the Buffer is reached,
  85. else -1 on an error.
  86. --*/
  87. {
  88. va_list ArgList;
  89. int FormatItems;
  90. va_start(ArgList, Format);
  91. for (FormatItems = 0;;) {
  92. switch (*Format) {
  93. case 0:
  94. return (MaximumLength && *Buffer) ? -1 : FormatItems;
  95. case '%':
  96. Format++;
  97. if (*Format != '%') {
  98. ULONG Number;
  99. int Width;
  100. int Long;
  101. PVOID Pointer;
  102. for (Long = 0, Width = 0;; Format++) {
  103. if ((*Format >= '0') && (*Format <= '9')) {
  104. Width = Width * 10 + *Format - '0';
  105. } else if (*Format == 'l') {
  106. Long++;
  107. } else if ((*Format == 'X') || (*Format == 'x')) {
  108. break;
  109. }
  110. }
  111. Format++;
  112. for (Number = 0; Width--; Buffer++, MaximumLength--) {
  113. if (!MaximumLength)
  114. return -1;
  115. Number *= 16;
  116. if ((*Buffer >= '0') && (*Buffer <= '9')) {
  117. Number += (*Buffer - '0');
  118. } else if ((*Buffer >= 'a') && (*Buffer <= 'f')) {
  119. Number += (*Buffer - 'a' + 10);
  120. } else if ((*Buffer >= 'A') && (*Buffer <= 'F')) {
  121. Number += (*Buffer - 'A' + 10);
  122. } else {
  123. return -1;
  124. }
  125. }
  126. Pointer = va_arg(ArgList, PVOID);
  127. if (Long) {
  128. *(PULONG)Pointer = Number;
  129. } else {
  130. *(PUSHORT)Pointer = (USHORT)Number;
  131. }
  132. FormatItems++;
  133. break;
  134. }
  135. /* no break */
  136. default:
  137. if (!MaximumLength || (*Buffer != *Format)) {
  138. return -1;
  139. }
  140. Buffer++;
  141. MaximumLength--;
  142. Format++;
  143. break;
  144. }
  145. }
  146. }
  147. NTSYSAPI
  148. NTSTATUS
  149. NTAPI
  150. RtlGUIDFromString(
  151. IN PUNICODE_STRING GuidString,
  152. OUT GUID* Guid
  153. )
  154. /*++
  155. Routine Description:
  156. Retrieves a the binary format of a textual GUID presented in the standard
  157. string version of a GUID: "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}".
  158. Arguments:
  159. GuidString -
  160. Place from which to retrieve the textual form of the GUID.
  161. Guid -
  162. Place in which to put the binary form of the GUID.
  163. Return Value:
  164. Returns STATUS_SUCCESS if the buffer contained a valid GUID, else
  165. STATUS_INVALID_PARAMETER if the string was invalid.
  166. --*/
  167. {
  168. USHORT Data4[8];
  169. int Count;
  170. RTL_PAGED_CODE();
  171. 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) {
  172. return STATUS_INVALID_PARAMETER;
  173. }
  174. for (Count = 0; Count < sizeof(Data4)/sizeof(Data4[0]); Count++) {
  175. Guid->Data4[Count] = (UCHAR)Data4[Count];
  176. }
  177. return STATUS_SUCCESS;
  178. }