]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/SafeString.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / BaseLib / SafeString.c
CommitLineData
c058d59f
JY
1/** @file\r
2 Safe String functions.\r
3\r
5dbfa01e 4 Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>\r
9344f092 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
c058d59f
JY
6\r
7**/\r
8\r
d8af3301 9#include "BaseLibInternals.h"\r
c058d59f
JY
10\r
11#define RSIZE_MAX (PcdGet32 (PcdMaximumUnicodeStringLength))\r
12\r
13#define ASCII_RSIZE_MAX (PcdGet32 (PcdMaximumAsciiStringLength))\r
14\r
15#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \\r
16 do { \\r
c058d59f 17 if (!(Expression)) { \\r
09fe015a
VC
18 DEBUG ((DEBUG_VERBOSE, \\r
19 "%a(%d) %a: SAFE_STRING_CONSTRAINT_CHECK(%a) failed. Return %r\n", \\r
5948ec36 20 __FILE__, DEBUG_LINE_NUMBER, __FUNCTION__, DEBUG_EXPRESSION_STRING (Expression), Status)); \\r
c058d59f
JY
21 return Status; \\r
22 } \\r
23 } while (FALSE)\r
24\r
25/**\r
26 Returns if 2 memory blocks are overlapped.\r
27\r
28 @param Base1 Base address of 1st memory block.\r
29 @param Size1 Size of 1st memory block.\r
30 @param Base2 Base address of 2nd memory block.\r
31 @param Size2 Size of 2nd memory block.\r
32\r
33 @retval TRUE 2 memory blocks are overlapped.\r
34 @retval FALSE 2 memory blocks are not overlapped.\r
35**/\r
36BOOLEAN\r
37InternalSafeStringIsOverlap (\r
2f88bd3a
MK
38 IN VOID *Base1,\r
39 IN UINTN Size1,\r
40 IN VOID *Base2,\r
41 IN UINTN Size2\r
c058d59f
JY
42 )\r
43{\r
44 if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||\r
2f88bd3a
MK
45 (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1)))\r
46 {\r
c058d59f
JY
47 return TRUE;\r
48 }\r
2f88bd3a 49\r
c058d59f
JY
50 return FALSE;\r
51}\r
52\r
53/**\r
54 Returns if 2 Unicode strings are not overlapped.\r
55\r
56 @param Str1 Start address of 1st Unicode string.\r
57 @param Size1 The number of char in 1st Unicode string,\r
58 including terminating null char.\r
59 @param Str2 Start address of 2nd Unicode string.\r
60 @param Size2 The number of char in 2nd Unicode string,\r
61 including terminating null char.\r
62\r
63 @retval TRUE 2 Unicode strings are NOT overlapped.\r
64 @retval FALSE 2 Unicode strings are overlapped.\r
65**/\r
66BOOLEAN\r
67InternalSafeStringNoStrOverlap (\r
68 IN CHAR16 *Str1,\r
69 IN UINTN Size1,\r
70 IN CHAR16 *Str2,\r
71 IN UINTN Size2\r
72 )\r
73{\r
2f88bd3a 74 return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof (CHAR16), Str2, Size2 * sizeof (CHAR16));\r
c058d59f
JY
75}\r
76\r
77/**\r
78 Returns if 2 Ascii strings are not overlapped.\r
79\r
80 @param Str1 Start address of 1st Ascii string.\r
81 @param Size1 The number of char in 1st Ascii string,\r
82 including terminating null char.\r
83 @param Str2 Start address of 2nd Ascii string.\r
84 @param Size2 The number of char in 2nd Ascii string,\r
85 including terminating null char.\r
86\r
87 @retval TRUE 2 Ascii strings are NOT overlapped.\r
88 @retval FALSE 2 Ascii strings are overlapped.\r
89**/\r
90BOOLEAN\r
91InternalSafeStringNoAsciiStrOverlap (\r
2f88bd3a
MK
92 IN CHAR8 *Str1,\r
93 IN UINTN Size1,\r
94 IN CHAR8 *Str2,\r
95 IN UINTN Size2\r
c058d59f
JY
96 )\r
97{\r
98 return !InternalSafeStringIsOverlap (Str1, Size1, Str2, Size2);\r
99}\r
100\r
101/**\r
102 Returns the length of a Null-terminated Unicode string.\r
103\r
328f84b1
JY
104 This function is similar as strlen_s defined in C11.\r
105\r
c058d59f
JY
106 If String is not aligned on a 16-bit boundary, then ASSERT().\r
107\r
108 @param String A pointer to a Null-terminated Unicode string.\r
109 @param MaxSize The maximum number of Destination Unicode\r
110 char, including terminating null char.\r
111\r
112 @retval 0 If String is NULL.\r
113 @retval MaxSize If there is no null character in the first MaxSize characters of String.\r
114 @return The number of characters that percede the terminating null character.\r
115\r
116**/\r
117UINTN\r
118EFIAPI\r
119StrnLenS (\r
2f88bd3a
MK
120 IN CONST CHAR16 *String,\r
121 IN UINTN MaxSize\r
c058d59f
JY
122 )\r
123{\r
2f88bd3a 124 UINTN Length;\r
c058d59f 125\r
2f88bd3a 126 ASSERT (((UINTN)String & BIT0) == 0);\r
c058d59f
JY
127\r
128 //\r
cb867499 129 // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.\r
c058d59f 130 //\r
cb867499 131 if ((String == NULL) || (MaxSize == 0)) {\r
c058d59f
JY
132 return 0;\r
133 }\r
134\r
135 //\r
136 // Otherwise, the StrnLenS function returns the number of characters that precede the\r
137 // terminating null character. If there is no null character in the first MaxSize characters of\r
138 // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall\r
139 // be accessed by StrnLenS.\r
140 //\r
c07c517c
HW
141 Length = 0;\r
142 while (String[Length] != 0) {\r
143 if (Length >= MaxSize - 1) {\r
144 return MaxSize;\r
145 }\r
2f88bd3a 146\r
c07c517c 147 Length++;\r
c058d59f 148 }\r
2f88bd3a 149\r
c058d59f
JY
150 return Length;\r
151}\r
152\r
b590e43a
HW
153/**\r
154 Returns the size of a Null-terminated Unicode string in bytes, including the\r
155 Null terminator.\r
156\r
157 This function returns the size of the Null-terminated Unicode string\r
158 specified by String in bytes, including the Null terminator.\r
159\r
160 If String is not aligned on a 16-bit boundary, then ASSERT().\r
161\r
162 @param String A pointer to a Null-terminated Unicode string.\r
163 @param MaxSize The maximum number of Destination Unicode\r
164 char, including the Null terminator.\r
165\r
166 @retval 0 If String is NULL.\r
167 @retval (sizeof (CHAR16) * (MaxSize + 1))\r
168 If there is no Null terminator in the first MaxSize characters of\r
169 String.\r
170 @return The size of the Null-terminated Unicode string in bytes, including\r
171 the Null terminator.\r
172\r
173**/\r
174UINTN\r
175EFIAPI\r
176StrnSizeS (\r
2f88bd3a
MK
177 IN CONST CHAR16 *String,\r
178 IN UINTN MaxSize\r
b590e43a
HW
179 )\r
180{\r
181 //\r
182 // If String is a null pointer, then the StrnSizeS function returns zero.\r
183 //\r
184 if (String == NULL) {\r
185 return 0;\r
186 }\r
187\r
188 //\r
189 // Otherwise, the StrnSizeS function returns the size of the Null-terminated\r
190 // Unicode string in bytes, including the Null terminator. If there is no\r
191 // Null terminator in the first MaxSize characters of String, then StrnSizeS\r
192 // returns (sizeof (CHAR16) * (MaxSize + 1)) to keep a consistent map with\r
193 // the StrnLenS function.\r
194 //\r
195 return (StrnLenS (String, MaxSize) + 1) * sizeof (*String);\r
196}\r
197\r
c058d59f
JY
198/**\r
199 Copies the string pointed to by Source (including the terminating null char)\r
200 to the array pointed to by Destination.\r
201\r
328f84b1
JY
202 This function is similar as strcpy_s defined in C11.\r
203\r
c058d59f
JY
204 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
205 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
206\r
328f84b1
JY
207 If an error is returned, then the Destination is unmodified.\r
208\r
c058d59f
JY
209 @param Destination A pointer to a Null-terminated Unicode string.\r
210 @param DestMax The maximum number of Destination Unicode\r
211 char, including terminating null char.\r
212 @param Source A pointer to a Null-terminated Unicode string.\r
213\r
214 @retval RETURN_SUCCESS String is copied.\r
215 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
216 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
217 If Source is NULL.\r
218 If PcdMaximumUnicodeStringLength is not zero,\r
973f8862 219 and DestMax is greater than\r
c058d59f
JY
220 PcdMaximumUnicodeStringLength.\r
221 If DestMax is 0.\r
222 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
223**/\r
224RETURN_STATUS\r
225EFIAPI\r
226StrCpyS (\r
2f88bd3a
MK
227 OUT CHAR16 *Destination,\r
228 IN UINTN DestMax,\r
229 IN CONST CHAR16 *Source\r
c058d59f
JY
230 )\r
231{\r
2f88bd3a 232 UINTN SourceLen;\r
973f8862 233\r
2f88bd3a
MK
234 ASSERT (((UINTN)Destination & BIT0) == 0);\r
235 ASSERT (((UINTN)Source & BIT0) == 0);\r
c058d59f
JY
236\r
237 //\r
238 // 1. Neither Destination nor Source shall be a null pointer.\r
239 //\r
240 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
241 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
242\r
243 //\r
244 // 2. DestMax shall not be greater than RSIZE_MAX.\r
245 //\r
246 if (RSIZE_MAX != 0) {\r
247 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
248 }\r
249\r
250 //\r
251 // 3. DestMax shall not equal zero.\r
252 //\r
253 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
254\r
255 //\r
256 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).\r
257 //\r
258 SourceLen = StrnLenS (Source, DestMax);\r
259 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
260\r
261 //\r
262 // 5. Copying shall not take place between objects that overlap.\r
263 //\r
264 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
265\r
266 //\r
267 // The StrCpyS function copies the string pointed to by Source (including the terminating\r
268 // null character) into the array pointed to by Destination.\r
269 //\r
270 while (*Source != 0) {\r
271 *(Destination++) = *(Source++);\r
272 }\r
2f88bd3a 273\r
c058d59f
JY
274 *Destination = 0;\r
275\r
276 return RETURN_SUCCESS;\r
277}\r
278\r
279/**\r
280 Copies not more than Length successive char from the string pointed to by\r
281 Source to the array pointed to by Destination. If no null char is copied from\r
282 Source, then Destination[Length] is always set to null.\r
283\r
328f84b1
JY
284 This function is similar as strncpy_s defined in C11.\r
285\r
c058d59f
JY
286 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().\r
287 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().\r
288\r
328f84b1
JY
289 If an error is returned, then the Destination is unmodified.\r
290\r
c058d59f
JY
291 @param Destination A pointer to a Null-terminated Unicode string.\r
292 @param DestMax The maximum number of Destination Unicode\r
293 char, including terminating null char.\r
294 @param Source A pointer to a Null-terminated Unicode string.\r
295 @param Length The maximum number of Unicode characters to copy.\r
296\r
297 @retval RETURN_SUCCESS String is copied.\r
973f8862 298 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than\r
c058d59f
JY
299 MIN(StrLen(Source), Length).\r
300 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
301 If Source is NULL.\r
302 If PcdMaximumUnicodeStringLength is not zero,\r
973f8862 303 and DestMax is greater than\r
c058d59f
JY
304 PcdMaximumUnicodeStringLength.\r
305 If DestMax is 0.\r
306 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
307**/\r
308RETURN_STATUS\r
309EFIAPI\r
310StrnCpyS (\r
2f88bd3a
MK
311 OUT CHAR16 *Destination,\r
312 IN UINTN DestMax,\r
313 IN CONST CHAR16 *Source,\r
314 IN UINTN Length\r
c058d59f
JY
315 )\r
316{\r
2f88bd3a 317 UINTN SourceLen;\r
c058d59f 318\r
2f88bd3a
MK
319 ASSERT (((UINTN)Destination & BIT0) == 0);\r
320 ASSERT (((UINTN)Source & BIT0) == 0);\r
c058d59f
JY
321\r
322 //\r
323 // 1. Neither Destination nor Source shall be a null pointer.\r
324 //\r
325 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
326 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
327\r
328 //\r
329 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX\r
330 //\r
331 if (RSIZE_MAX != 0) {\r
332 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
333 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
334 }\r
335\r
336 //\r
337 // 3. DestMax shall not equal zero.\r
338 //\r
339 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
340\r
341 //\r
342 // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).\r
343 //\r
56658c22 344 SourceLen = StrnLenS (Source, MIN (DestMax, Length));\r
c058d59f
JY
345 if (Length >= DestMax) {\r
346 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
347 }\r
348\r
349 //\r
350 // 5. Copying shall not take place between objects that overlap.\r
351 //\r
352 if (SourceLen > Length) {\r
353 SourceLen = Length;\r
354 }\r
2f88bd3a 355\r
c058d59f
JY
356 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
357\r
358 //\r
359 // The StrnCpyS function copies not more than Length successive characters (characters that\r
360 // follow a null character are not copied) from the array pointed to by Source to the array\r
361 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null\r
362 // character.\r
363 //\r
56658c22 364 while ((SourceLen > 0) && (*Source != 0)) {\r
c058d59f
JY
365 *(Destination++) = *(Source++);\r
366 SourceLen--;\r
367 }\r
2f88bd3a 368\r
c058d59f
JY
369 *Destination = 0;\r
370\r
371 return RETURN_SUCCESS;\r
372}\r
373\r
374/**\r
375 Appends a copy of the string pointed to by Source (including the terminating\r
376 null char) to the end of the string pointed to by Destination.\r
377\r
328f84b1
JY
378 This function is similar as strcat_s defined in C11.\r
379\r
c058d59f
JY
380 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
381 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
382\r
328f84b1
JY
383 If an error is returned, then the Destination is unmodified.\r
384\r
c058d59f
JY
385 @param Destination A pointer to a Null-terminated Unicode string.\r
386 @param DestMax The maximum number of Destination Unicode\r
387 char, including terminating null char.\r
388 @param Source A pointer to a Null-terminated Unicode string.\r
389\r
390 @retval RETURN_SUCCESS String is appended.\r
973f8862 391 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than\r
c058d59f
JY
392 StrLen(Destination).\r
393 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
394 greater than StrLen(Source).\r
395 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
396 If Source is NULL.\r
397 If PcdMaximumUnicodeStringLength is not zero,\r
973f8862 398 and DestMax is greater than\r
c058d59f
JY
399 PcdMaximumUnicodeStringLength.\r
400 If DestMax is 0.\r
401 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
402**/\r
403RETURN_STATUS\r
404EFIAPI\r
405StrCatS (\r
2f88bd3a
MK
406 IN OUT CHAR16 *Destination,\r
407 IN UINTN DestMax,\r
408 IN CONST CHAR16 *Source\r
c058d59f
JY
409 )\r
410{\r
2f88bd3a
MK
411 UINTN DestLen;\r
412 UINTN CopyLen;\r
413 UINTN SourceLen;\r
973f8862 414\r
2f88bd3a
MK
415 ASSERT (((UINTN)Destination & BIT0) == 0);\r
416 ASSERT (((UINTN)Source & BIT0) == 0);\r
c058d59f
JY
417\r
418 //\r
419 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.\r
420 //\r
421 DestLen = StrnLenS (Destination, DestMax);\r
422 CopyLen = DestMax - DestLen;\r
423\r
424 //\r
425 // 1. Neither Destination nor Source shall be a null pointer.\r
426 //\r
427 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
428 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
429\r
430 //\r
431 // 2. DestMax shall not be greater than RSIZE_MAX.\r
432 //\r
433 if (RSIZE_MAX != 0) {\r
434 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
435 }\r
436\r
437 //\r
438 // 3. DestMax shall not equal zero.\r
439 //\r
440 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
441\r
442 //\r
443 // 4. CopyLen shall not equal zero.\r
444 //\r
445 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
446\r
447 //\r
448 // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).\r
449 //\r
450 SourceLen = StrnLenS (Source, CopyLen);\r
451 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
452\r
453 //\r
454 // 6. Copying shall not take place between objects that overlap.\r
455 //\r
456 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
457\r
458 //\r
459 // The StrCatS function appends a copy of the string pointed to by Source (including the\r
460 // terminating null character) to the end of the string pointed to by Destination. The initial character\r
461 // from Source overwrites the null character at the end of Destination.\r
462 //\r
463 Destination = Destination + DestLen;\r
464 while (*Source != 0) {\r
465 *(Destination++) = *(Source++);\r
466 }\r
2f88bd3a 467\r
c058d59f
JY
468 *Destination = 0;\r
469\r
470 return RETURN_SUCCESS;\r
471}\r
472\r
473/**\r
474 Appends not more than Length successive char from the string pointed to by\r
475 Source to the end of the string pointed to by Destination. If no null char is\r
476 copied from Source, then Destination[StrLen(Destination) + Length] is always\r
477 set to null.\r
478\r
328f84b1
JY
479 This function is similar as strncat_s defined in C11.\r
480\r
c058d59f 481 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
0e93edbb 482 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
c058d59f 483\r
328f84b1
JY
484 If an error is returned, then the Destination is unmodified.\r
485\r
c058d59f
JY
486 @param Destination A pointer to a Null-terminated Unicode string.\r
487 @param DestMax The maximum number of Destination Unicode\r
488 char, including terminating null char.\r
489 @param Source A pointer to a Null-terminated Unicode string.\r
490 @param Length The maximum number of Unicode characters to copy.\r
491\r
492 @retval RETURN_SUCCESS String is appended.\r
493 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than\r
494 StrLen(Destination).\r
495 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
496 greater than MIN(StrLen(Source), Length).\r
497 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
498 If Source is NULL.\r
499 If PcdMaximumUnicodeStringLength is not zero,\r
973f8862 500 and DestMax is greater than\r
c058d59f
JY
501 PcdMaximumUnicodeStringLength.\r
502 If DestMax is 0.\r
503 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
504**/\r
505RETURN_STATUS\r
506EFIAPI\r
507StrnCatS (\r
2f88bd3a
MK
508 IN OUT CHAR16 *Destination,\r
509 IN UINTN DestMax,\r
510 IN CONST CHAR16 *Source,\r
511 IN UINTN Length\r
c058d59f
JY
512 )\r
513{\r
2f88bd3a
MK
514 UINTN DestLen;\r
515 UINTN CopyLen;\r
516 UINTN SourceLen;\r
973f8862 517\r
2f88bd3a
MK
518 ASSERT (((UINTN)Destination & BIT0) == 0);\r
519 ASSERT (((UINTN)Source & BIT0) == 0);\r
c058d59f
JY
520\r
521 //\r
522 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.\r
523 //\r
524 DestLen = StrnLenS (Destination, DestMax);\r
525 CopyLen = DestMax - DestLen;\r
526\r
527 //\r
528 // 1. Neither Destination nor Source shall be a null pointer.\r
529 //\r
530 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
531 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
532\r
533 //\r
534 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.\r
535 //\r
536 if (RSIZE_MAX != 0) {\r
537 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
538 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
539 }\r
540\r
541 //\r
542 // 3. DestMax shall not equal zero.\r
543 //\r
544 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
545\r
546 //\r
547 // 4. CopyLen shall not equal zero.\r
548 //\r
549 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
550\r
551 //\r
552 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).\r
553 //\r
56658c22 554 SourceLen = StrnLenS (Source, MIN (CopyLen, Length));\r
c058d59f
JY
555 if (Length >= CopyLen) {\r
556 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
557 }\r
558\r
559 //\r
560 // 6. Copying shall not take place between objects that overlap.\r
561 //\r
562 if (SourceLen > Length) {\r
563 SourceLen = Length;\r
564 }\r
2f88bd3a 565\r
c058d59f
JY
566 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
567\r
568 //\r
569 // The StrnCatS function appends not more than Length successive characters (characters\r
570 // that follow a null character are not copied) from the array pointed to by Source to the end of\r
571 // the string pointed to by Destination. The initial character from Source overwrites the null character at\r
572 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to\r
573 // a null character.\r
574 //\r
575 Destination = Destination + DestLen;\r
56658c22 576 while ((SourceLen > 0) && (*Source != 0)) {\r
c058d59f
JY
577 *(Destination++) = *(Source++);\r
578 SourceLen--;\r
579 }\r
2f88bd3a 580\r
c058d59f
JY
581 *Destination = 0;\r
582\r
583 return RETURN_SUCCESS;\r
584}\r
585\r
d8af3301
HW
586/**\r
587 Convert a Null-terminated Unicode decimal string to a value of type UINTN.\r
588\r
589 This function outputs a value of type UINTN by interpreting the contents of\r
590 the Unicode string specified by String as a decimal number. The format of the\r
591 input Unicode string String is:\r
592\r
593 [spaces] [decimal digits].\r
594\r
595 The valid decimal digit character is in the range [0-9]. The function will\r
596 ignore the pad space, which includes spaces or tab characters, before\r
597 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
598 be ignored. Then, the function stops at the first character that is a not a\r
599 valid decimal character or a Null-terminator, whichever one comes first.\r
600\r
d8af3301 601 If String is not aligned in a 16-bit boundary, then ASSERT().\r
d8af3301
HW
602\r
603 If String has no valid decimal digits in the above format, then 0 is stored\r
604 at the location pointed to by Data.\r
605 If the number represented by String exceeds the range defined by UINTN, then\r
606 MAX_UINTN is stored at the location pointed to by Data.\r
607\r
608 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
609 is stored at the location pointed to by EndPointer. If String has no valid\r
610 decimal digits right after the optional pad spaces, the value of String is\r
611 stored at the location pointed to by EndPointer.\r
612\r
613 @param String Pointer to a Null-terminated Unicode string.\r
614 @param EndPointer Pointer to character that stops scan.\r
615 @param Data Pointer to the converted value.\r
616\r
617 @retval RETURN_SUCCESS Value is translated from String.\r
618 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
619 If Data is NULL.\r
620 If PcdMaximumUnicodeStringLength is not\r
621 zero, and String contains more than\r
622 PcdMaximumUnicodeStringLength Unicode\r
623 characters, not including the\r
624 Null-terminator.\r
625 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
626 the range defined by UINTN.\r
627\r
628**/\r
629RETURN_STATUS\r
630EFIAPI\r
631StrDecimalToUintnS (\r
2f88bd3a
MK
632 IN CONST CHAR16 *String,\r
633 OUT CHAR16 **EndPointer OPTIONAL,\r
634 OUT UINTN *Data\r
d8af3301
HW
635 )\r
636{\r
2f88bd3a 637 ASSERT (((UINTN)String & BIT0) == 0);\r
d8af3301
HW
638\r
639 //\r
640 // 1. Neither String nor Data shall be a null pointer.\r
641 //\r
642 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
643 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
644\r
645 //\r
646 // 2. The length of String shall not be greater than RSIZE_MAX.\r
647 //\r
648 if (RSIZE_MAX != 0) {\r
649 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
650 }\r
651\r
652 if (EndPointer != NULL) {\r
2f88bd3a 653 *EndPointer = (CHAR16 *)String;\r
d8af3301
HW
654 }\r
655\r
656 //\r
657 // Ignore the pad spaces (space or tab)\r
658 //\r
659 while ((*String == L' ') || (*String == L'\t')) {\r
660 String++;\r
661 }\r
662\r
663 //\r
664 // Ignore leading Zeros after the spaces\r
665 //\r
666 while (*String == L'0') {\r
667 String++;\r
668 }\r
669\r
670 *Data = 0;\r
671\r
672 while (InternalIsDecimalDigitCharacter (*String)) {\r
673 //\r
674 // If the number represented by String overflows according to the range\r
675 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
676 // RETURN_UNSUPPORTED is returned.\r
677 //\r
678 if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) {\r
679 *Data = MAX_UINTN;\r
680 if (EndPointer != NULL) {\r
2f88bd3a 681 *EndPointer = (CHAR16 *)String;\r
d8af3301 682 }\r
2f88bd3a 683\r
d8af3301
HW
684 return RETURN_UNSUPPORTED;\r
685 }\r
686\r
687 *Data = *Data * 10 + (*String - L'0');\r
688 String++;\r
689 }\r
690\r
691 if (EndPointer != NULL) {\r
2f88bd3a 692 *EndPointer = (CHAR16 *)String;\r
d8af3301 693 }\r
2f88bd3a 694\r
d8af3301
HW
695 return RETURN_SUCCESS;\r
696}\r
697\r
698/**\r
699 Convert a Null-terminated Unicode decimal string to a value of type UINT64.\r
700\r
701 This function outputs a value of type UINT64 by interpreting the contents of\r
702 the Unicode string specified by String as a decimal number. The format of the\r
703 input Unicode string String is:\r
704\r
705 [spaces] [decimal digits].\r
706\r
707 The valid decimal digit character is in the range [0-9]. The function will\r
708 ignore the pad space, which includes spaces or tab characters, before\r
709 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
710 be ignored. Then, the function stops at the first character that is a not a\r
711 valid decimal character or a Null-terminator, whichever one comes first.\r
712\r
d8af3301 713 If String is not aligned in a 16-bit boundary, then ASSERT().\r
d8af3301
HW
714\r
715 If String has no valid decimal digits in the above format, then 0 is stored\r
716 at the location pointed to by Data.\r
717 If the number represented by String exceeds the range defined by UINT64, then\r
718 MAX_UINT64 is stored at the location pointed to by Data.\r
719\r
720 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
721 is stored at the location pointed to by EndPointer. If String has no valid\r
722 decimal digits right after the optional pad spaces, the value of String is\r
723 stored at the location pointed to by EndPointer.\r
724\r
725 @param String Pointer to a Null-terminated Unicode string.\r
726 @param EndPointer Pointer to character that stops scan.\r
727 @param Data Pointer to the converted value.\r
728\r
729 @retval RETURN_SUCCESS Value is translated from String.\r
730 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
731 If Data is NULL.\r
732 If PcdMaximumUnicodeStringLength is not\r
733 zero, and String contains more than\r
734 PcdMaximumUnicodeStringLength Unicode\r
735 characters, not including the\r
736 Null-terminator.\r
737 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
738 the range defined by UINT64.\r
739\r
740**/\r
741RETURN_STATUS\r
742EFIAPI\r
743StrDecimalToUint64S (\r
2f88bd3a
MK
744 IN CONST CHAR16 *String,\r
745 OUT CHAR16 **EndPointer OPTIONAL,\r
746 OUT UINT64 *Data\r
d8af3301
HW
747 )\r
748{\r
2f88bd3a 749 ASSERT (((UINTN)String & BIT0) == 0);\r
d8af3301
HW
750\r
751 //\r
752 // 1. Neither String nor Data shall be a null pointer.\r
753 //\r
754 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
755 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
756\r
757 //\r
758 // 2. The length of String shall not be greater than RSIZE_MAX.\r
759 //\r
760 if (RSIZE_MAX != 0) {\r
761 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
762 }\r
763\r
764 if (EndPointer != NULL) {\r
2f88bd3a 765 *EndPointer = (CHAR16 *)String;\r
d8af3301
HW
766 }\r
767\r
768 //\r
769 // Ignore the pad spaces (space or tab)\r
770 //\r
771 while ((*String == L' ') || (*String == L'\t')) {\r
772 String++;\r
773 }\r
774\r
775 //\r
776 // Ignore leading Zeros after the spaces\r
777 //\r
778 while (*String == L'0') {\r
779 String++;\r
780 }\r
781\r
782 *Data = 0;\r
783\r
784 while (InternalIsDecimalDigitCharacter (*String)) {\r
785 //\r
786 // If the number represented by String overflows according to the range\r
787 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
788 // RETURN_UNSUPPORTED is returned.\r
789 //\r
790 if (*Data > DivU64x32 (MAX_UINT64 - (*String - L'0'), 10)) {\r
791 *Data = MAX_UINT64;\r
792 if (EndPointer != NULL) {\r
2f88bd3a 793 *EndPointer = (CHAR16 *)String;\r
d8af3301 794 }\r
2f88bd3a 795\r
d8af3301
HW
796 return RETURN_UNSUPPORTED;\r
797 }\r
798\r
799 *Data = MultU64x32 (*Data, 10) + (*String - L'0');\r
800 String++;\r
801 }\r
802\r
803 if (EndPointer != NULL) {\r
2f88bd3a 804 *EndPointer = (CHAR16 *)String;\r
d8af3301 805 }\r
2f88bd3a 806\r
d8af3301
HW
807 return RETURN_SUCCESS;\r
808}\r
809\r
810/**\r
811 Convert a Null-terminated Unicode hexadecimal string to a value of type\r
812 UINTN.\r
813\r
814 This function outputs a value of type UINTN by interpreting the contents of\r
815 the Unicode string specified by String as a hexadecimal number. The format of\r
816 the input Unicode string String is:\r
817\r
818 [spaces][zeros][x][hexadecimal digits].\r
819\r
820 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
821 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
822 If "x" appears in the input string, it must be prefixed with at least one 0.\r
823 The function will ignore the pad space, which includes spaces or tab\r
824 characters, before [zeros], [x] or [hexadecimal digit]. The running zero\r
825 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts\r
826 after [x] or the first valid hexadecimal digit. Then, the function stops at\r
827 the first character that is a not a valid hexadecimal character or NULL,\r
828 whichever one comes first.\r
829\r
d8af3301 830 If String is not aligned in a 16-bit boundary, then ASSERT().\r
d8af3301
HW
831\r
832 If String has no valid hexadecimal digits in the above format, then 0 is\r
833 stored at the location pointed to by Data.\r
834 If the number represented by String exceeds the range defined by UINTN, then\r
835 MAX_UINTN is stored at the location pointed to by Data.\r
836\r
837 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
838 is stored at the location pointed to by EndPointer. If String has no valid\r
839 hexadecimal digits right after the optional pad spaces, the value of String\r
840 is stored at the location pointed to by EndPointer.\r
841\r
842 @param String Pointer to a Null-terminated Unicode string.\r
843 @param EndPointer Pointer to character that stops scan.\r
844 @param Data Pointer to the converted value.\r
845\r
846 @retval RETURN_SUCCESS Value is translated from String.\r
847 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
848 If Data is NULL.\r
849 If PcdMaximumUnicodeStringLength is not\r
850 zero, and String contains more than\r
851 PcdMaximumUnicodeStringLength Unicode\r
852 characters, not including the\r
853 Null-terminator.\r
854 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
855 the range defined by UINTN.\r
856\r
857**/\r
858RETURN_STATUS\r
859EFIAPI\r
860StrHexToUintnS (\r
2f88bd3a
MK
861 IN CONST CHAR16 *String,\r
862 OUT CHAR16 **EndPointer OPTIONAL,\r
863 OUT UINTN *Data\r
d8af3301
HW
864 )\r
865{\r
35043a5e
PF
866 BOOLEAN FoundLeadingZero;\r
867\r
868 FoundLeadingZero = FALSE;\r
2f88bd3a 869 ASSERT (((UINTN)String & BIT0) == 0);\r
d8af3301
HW
870\r
871 //\r
872 // 1. Neither String nor Data shall be a null pointer.\r
873 //\r
874 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
875 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
876\r
877 //\r
878 // 2. The length of String shall not be greater than RSIZE_MAX.\r
879 //\r
880 if (RSIZE_MAX != 0) {\r
881 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
882 }\r
883\r
884 if (EndPointer != NULL) {\r
2f88bd3a 885 *EndPointer = (CHAR16 *)String;\r
d8af3301
HW
886 }\r
887\r
888 //\r
889 // Ignore the pad spaces (space or tab)\r
890 //\r
891 while ((*String == L' ') || (*String == L'\t')) {\r
892 String++;\r
893 }\r
894\r
895 //\r
896 // Ignore leading Zeros after the spaces\r
897 //\r
35043a5e
PF
898\r
899 FoundLeadingZero = *String == L'0';\r
d8af3301
HW
900 while (*String == L'0') {\r
901 String++;\r
902 }\r
903\r
5dbfa01e 904 if (CharToUpper (*String) == L'X') {\r
35043a5e 905 if (!FoundLeadingZero) {\r
d8af3301
HW
906 *Data = 0;\r
907 return RETURN_SUCCESS;\r
908 }\r
2f88bd3a 909\r
d8af3301
HW
910 //\r
911 // Skip the 'X'\r
912 //\r
913 String++;\r
914 }\r
915\r
916 *Data = 0;\r
917\r
918 while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
919 //\r
920 // If the number represented by String overflows according to the range\r
921 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
922 // RETURN_UNSUPPORTED is returned.\r
923 //\r
924 if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) {\r
925 *Data = MAX_UINTN;\r
926 if (EndPointer != NULL) {\r
2f88bd3a 927 *EndPointer = (CHAR16 *)String;\r
d8af3301 928 }\r
2f88bd3a 929\r
d8af3301
HW
930 return RETURN_UNSUPPORTED;\r
931 }\r
932\r
933 *Data = (*Data << 4) + InternalHexCharToUintn (*String);\r
934 String++;\r
935 }\r
936\r
937 if (EndPointer != NULL) {\r
2f88bd3a 938 *EndPointer = (CHAR16 *)String;\r
d8af3301 939 }\r
2f88bd3a 940\r
d8af3301
HW
941 return RETURN_SUCCESS;\r
942}\r
943\r
944/**\r
945 Convert a Null-terminated Unicode hexadecimal string to a value of type\r
946 UINT64.\r
947\r
948 This function outputs a value of type UINT64 by interpreting the contents of\r
949 the Unicode string specified by String as a hexadecimal number. The format of\r
950 the input Unicode string String is:\r
951\r
952 [spaces][zeros][x][hexadecimal digits].\r
953\r
954 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
955 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
956 If "x" appears in the input string, it must be prefixed with at least one 0.\r
957 The function will ignore the pad space, which includes spaces or tab\r
958 characters, before [zeros], [x] or [hexadecimal digit]. The running zero\r
959 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts\r
960 after [x] or the first valid hexadecimal digit. Then, the function stops at\r
961 the first character that is a not a valid hexadecimal character or NULL,\r
962 whichever one comes first.\r
963\r
d8af3301 964 If String is not aligned in a 16-bit boundary, then ASSERT().\r
d8af3301
HW
965\r
966 If String has no valid hexadecimal digits in the above format, then 0 is\r
967 stored at the location pointed to by Data.\r
968 If the number represented by String exceeds the range defined by UINT64, then\r
969 MAX_UINT64 is stored at the location pointed to by Data.\r
970\r
971 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
972 is stored at the location pointed to by EndPointer. If String has no valid\r
973 hexadecimal digits right after the optional pad spaces, the value of String\r
974 is stored at the location pointed to by EndPointer.\r
975\r
976 @param String Pointer to a Null-terminated Unicode string.\r
977 @param EndPointer Pointer to character that stops scan.\r
978 @param Data Pointer to the converted value.\r
979\r
980 @retval RETURN_SUCCESS Value is translated from String.\r
981 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
982 If Data is NULL.\r
983 If PcdMaximumUnicodeStringLength is not\r
984 zero, and String contains more than\r
985 PcdMaximumUnicodeStringLength Unicode\r
986 characters, not including the\r
987 Null-terminator.\r
988 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
989 the range defined by UINT64.\r
990\r
991**/\r
992RETURN_STATUS\r
993EFIAPI\r
994StrHexToUint64S (\r
2f88bd3a
MK
995 IN CONST CHAR16 *String,\r
996 OUT CHAR16 **EndPointer OPTIONAL,\r
997 OUT UINT64 *Data\r
d8af3301
HW
998 )\r
999{\r
35043a5e
PF
1000 BOOLEAN FoundLeadingZero;\r
1001\r
1002 FoundLeadingZero = FALSE;\r
2f88bd3a 1003 ASSERT (((UINTN)String & BIT0) == 0);\r
d8af3301
HW
1004\r
1005 //\r
1006 // 1. Neither String nor Data shall be a null pointer.\r
1007 //\r
1008 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1009 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
1010\r
1011 //\r
1012 // 2. The length of String shall not be greater than RSIZE_MAX.\r
1013 //\r
1014 if (RSIZE_MAX != 0) {\r
1015 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1016 }\r
1017\r
1018 if (EndPointer != NULL) {\r
2f88bd3a 1019 *EndPointer = (CHAR16 *)String;\r
d8af3301
HW
1020 }\r
1021\r
1022 //\r
1023 // Ignore the pad spaces (space or tab)\r
1024 //\r
1025 while ((*String == L' ') || (*String == L'\t')) {\r
1026 String++;\r
1027 }\r
1028\r
1029 //\r
1030 // Ignore leading Zeros after the spaces\r
1031 //\r
35043a5e 1032 FoundLeadingZero = *String == L'0';\r
d8af3301
HW
1033 while (*String == L'0') {\r
1034 String++;\r
1035 }\r
1036\r
5dbfa01e 1037 if (CharToUpper (*String) == L'X') {\r
35043a5e 1038 if (!FoundLeadingZero) {\r
d8af3301
HW
1039 *Data = 0;\r
1040 return RETURN_SUCCESS;\r
1041 }\r
2f88bd3a 1042\r
d8af3301
HW
1043 //\r
1044 // Skip the 'X'\r
1045 //\r
1046 String++;\r
1047 }\r
1048\r
1049 *Data = 0;\r
1050\r
1051 while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
1052 //\r
1053 // If the number represented by String overflows according to the range\r
1054 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
1055 // RETURN_UNSUPPORTED is returned.\r
1056 //\r
1057 if (*Data > RShiftU64 (MAX_UINT64 - InternalHexCharToUintn (*String), 4)) {\r
1058 *Data = MAX_UINT64;\r
1059 if (EndPointer != NULL) {\r
2f88bd3a 1060 *EndPointer = (CHAR16 *)String;\r
d8af3301 1061 }\r
2f88bd3a 1062\r
d8af3301
HW
1063 return RETURN_UNSUPPORTED;\r
1064 }\r
1065\r
1066 *Data = LShiftU64 (*Data, 4) + InternalHexCharToUintn (*String);\r
1067 String++;\r
1068 }\r
1069\r
1070 if (EndPointer != NULL) {\r
2f88bd3a 1071 *EndPointer = (CHAR16 *)String;\r
d8af3301 1072 }\r
2f88bd3a 1073\r
d8af3301
HW
1074 return RETURN_SUCCESS;\r
1075}\r
1076\r
36396ea2
RN
1077/**\r
1078 Convert a Null-terminated Unicode string to IPv6 address and prefix length.\r
1079\r
1080 This function outputs a value of type IPv6_ADDRESS and may output a value\r
1081 of type UINT8 by interpreting the contents of the Unicode string specified\r
1082 by String. The format of the input Unicode string String is as follows:\r
1083\r
1084 X:X:X:X:X:X:X:X[/P]\r
1085\r
1086 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and\r
1087 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low\r
1088 memory address and high byte is stored in high memory address. P contains decimal\r
1089 digit characters in the range [0-9]. The running zero in the beginning of P will\r
1090 be ignored. /P is optional.\r
1091\r
1092 When /P is not in the String, the function stops at the first character that is\r
1093 not a valid hexadecimal digit character after eight X's are converted.\r
1094\r
1095 When /P is in the String, the function stops at the first character that is not\r
1096 a valid decimal digit character after P is converted.\r
1097\r
1098 "::" can be used to compress one or more groups of X when X contains only 0.\r
1099 The "::" can only appear once in the String.\r
1100\r
36396ea2
RN
1101 If String is not aligned in a 16-bit boundary, then ASSERT().\r
1102\r
36396ea2
RN
1103 If EndPointer is not NULL and Address is translated from String, a pointer\r
1104 to the character that stopped the scan is stored at the location pointed to\r
1105 by EndPointer.\r
1106\r
1107 @param String Pointer to a Null-terminated Unicode string.\r
1108 @param EndPointer Pointer to character that stops scan.\r
1109 @param Address Pointer to the converted IPv6 address.\r
1110 @param PrefixLength Pointer to the converted IPv6 address prefix\r
1111 length. MAX_UINT8 is returned when /P is\r
1112 not in the String.\r
1113\r
1114 @retval RETURN_SUCCESS Address is translated from String.\r
1115 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1116 If Data is NULL.\r
1117 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal\r
1118 digit characters.\r
1119 If String contains "::" and number of X\r
1120 is not less than 8.\r
1121 If P starts with character that is not a\r
1122 valid decimal digit character.\r
1123 If the decimal number converted from P\r
1124 exceeds 128.\r
1125\r
1126**/\r
1127RETURN_STATUS\r
1128EFIAPI\r
1129StrToIpv6Address (\r
2f88bd3a
MK
1130 IN CONST CHAR16 *String,\r
1131 OUT CHAR16 **EndPointer OPTIONAL,\r
1132 OUT IPv6_ADDRESS *Address,\r
1133 OUT UINT8 *PrefixLength OPTIONAL\r
36396ea2
RN
1134 )\r
1135{\r
2f88bd3a
MK
1136 RETURN_STATUS Status;\r
1137 UINTN AddressIndex;\r
1138 UINTN Uintn;\r
1139 IPv6_ADDRESS LocalAddress;\r
1140 UINT8 LocalPrefixLength;\r
1141 CONST CHAR16 *Pointer;\r
1142 CHAR16 *End;\r
1143 UINTN CompressStart;\r
1144 BOOLEAN ExpectPrefix;\r
36396ea2
RN
1145\r
1146 LocalPrefixLength = MAX_UINT8;\r
1147 CompressStart = ARRAY_SIZE (Address->Addr);\r
1148 ExpectPrefix = FALSE;\r
1149\r
2f88bd3a 1150 ASSERT (((UINTN)String & BIT0) == 0);\r
36396ea2
RN
1151\r
1152 //\r
1153 // 1. None of String or Guid shall be a null pointer.\r
1154 //\r
1155 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1156 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);\r
1157\r
1158 for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {\r
1159 if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {\r
1160 if (*Pointer != L':') {\r
1161 //\r
1162 // ":" or "/" should be followed by digit characters.\r
1163 //\r
1164 return RETURN_UNSUPPORTED;\r
1165 }\r
1166\r
1167 //\r
1168 // Meet second ":" after previous ":" or "/"\r
1169 // or meet first ":" in the beginning of String.\r
1170 //\r
1171 if (ExpectPrefix) {\r
1172 //\r
1173 // ":" shall not be after "/"\r
1174 //\r
1175 return RETURN_UNSUPPORTED;\r
1176 }\r
1177\r
2f88bd3a 1178 if ((CompressStart != ARRAY_SIZE (Address->Addr)) || (AddressIndex == ARRAY_SIZE (Address->Addr))) {\r
36396ea2
RN
1179 //\r
1180 // "::" can only appear once.\r
1181 // "::" can only appear when address is not full length.\r
1182 //\r
1183 return RETURN_UNSUPPORTED;\r
1184 } else {\r
1185 //\r
1186 // Remember the start of zero compressing.\r
1187 //\r
1188 CompressStart = AddressIndex;\r
1189 Pointer++;\r
1190\r
1191 if (CompressStart == 0) {\r
1192 if (*Pointer != L':') {\r
1193 //\r
1194 // Single ":" shall not be in the beginning of String.\r
1195 //\r
1196 return RETURN_UNSUPPORTED;\r
1197 }\r
2f88bd3a 1198\r
36396ea2
RN
1199 Pointer++;\r
1200 }\r
1201 }\r
1202 }\r
1203\r
1204 if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {\r
1205 if (*Pointer == L'/') {\r
1206 //\r
1207 // Might be optional "/P" after "::".\r
1208 //\r
1209 if (CompressStart != AddressIndex) {\r
1210 return RETURN_UNSUPPORTED;\r
1211 }\r
1212 } else {\r
1213 break;\r
1214 }\r
1215 } else {\r
1216 if (!ExpectPrefix) {\r
1217 //\r
1218 // Get X.\r
1219 //\r
1220 Status = StrHexToUintnS (Pointer, &End, &Uintn);\r
2f88bd3a 1221 if (RETURN_ERROR (Status) || (End - Pointer > 4)) {\r
36396ea2
RN
1222 //\r
1223 // Number of hexadecimal digit characters is no more than 4.\r
1224 //\r
1225 return RETURN_UNSUPPORTED;\r
1226 }\r
2f88bd3a 1227\r
36396ea2
RN
1228 Pointer = End;\r
1229 //\r
1230 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.\r
1231 //\r
5b0ce08a 1232 ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));\r
2f88bd3a
MK
1233 LocalAddress.Addr[AddressIndex] = (UINT8)((UINT16)Uintn >> 8);\r
1234 LocalAddress.Addr[AddressIndex + 1] = (UINT8)Uintn;\r
1235 AddressIndex += 2;\r
36396ea2
RN
1236 } else {\r
1237 //\r
1238 // Get P, then exit the loop.\r
1239 //\r
1240 Status = StrDecimalToUintnS (Pointer, &End, &Uintn);\r
2f88bd3a 1241 if (RETURN_ERROR (Status) || (End == Pointer) || (Uintn > 128)) {\r
36396ea2
RN
1242 //\r
1243 // Prefix length should not exceed 128.\r
1244 //\r
1245 return RETURN_UNSUPPORTED;\r
1246 }\r
2f88bd3a
MK
1247\r
1248 LocalPrefixLength = (UINT8)Uintn;\r
1249 Pointer = End;\r
36396ea2
RN
1250 break;\r
1251 }\r
1252 }\r
1253\r
1254 //\r
1255 // Skip ':' or "/"\r
1256 //\r
1257 if (*Pointer == L'/') {\r
1258 ExpectPrefix = TRUE;\r
1259 } else if (*Pointer == L':') {\r
1260 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
1261 //\r
1262 // Meet additional ":" after all 8 16-bit address\r
1263 //\r
1264 break;\r
1265 }\r
1266 } else {\r
1267 //\r
1268 // Meet other character that is not "/" or ":" after all 8 16-bit address\r
1269 //\r
1270 break;\r
1271 }\r
2f88bd3a 1272\r
36396ea2
RN
1273 Pointer++;\r
1274 }\r
1275\r
2f88bd3a
MK
1276 if (((AddressIndex == ARRAY_SIZE (Address->Addr)) && (CompressStart != ARRAY_SIZE (Address->Addr))) ||\r
1277 ((AddressIndex != ARRAY_SIZE (Address->Addr)) && (CompressStart == ARRAY_SIZE (Address->Addr)))\r
1278 )\r
1279 {\r
36396ea2
RN
1280 //\r
1281 // Full length of address shall not have compressing zeros.\r
1282 // Non-full length of address shall have compressing zeros.\r
1283 //\r
1284 return RETURN_UNSUPPORTED;\r
1285 }\r
2f88bd3a 1286\r
36396ea2
RN
1287 CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);\r
1288 ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);\r
5b0ce08a
RN
1289 if (AddressIndex > CompressStart) {\r
1290 CopyMem (\r
1291 &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],\r
1292 &LocalAddress.Addr[CompressStart],\r
1293 AddressIndex - CompressStart\r
1294 );\r
1295 }\r
36396ea2
RN
1296\r
1297 if (PrefixLength != NULL) {\r
1298 *PrefixLength = LocalPrefixLength;\r
1299 }\r
2f88bd3a 1300\r
36396ea2 1301 if (EndPointer != NULL) {\r
2f88bd3a 1302 *EndPointer = (CHAR16 *)Pointer;\r
36396ea2
RN
1303 }\r
1304\r
1305 return RETURN_SUCCESS;\r
1306}\r
1307\r
1308/**\r
1309 Convert a Null-terminated Unicode string to IPv4 address and prefix length.\r
1310\r
1311 This function outputs a value of type IPv4_ADDRESS and may output a value\r
1312 of type UINT8 by interpreting the contents of the Unicode string specified\r
1313 by String. The format of the input Unicode string String is as follows:\r
1314\r
1315 D.D.D.D[/P]\r
1316\r
1317 D and P are decimal digit characters in the range [0-9]. The running zero in\r
1318 the beginning of D and P will be ignored. /P is optional.\r
1319\r
1320 When /P is not in the String, the function stops at the first character that is\r
1321 not a valid decimal digit character after four D's are converted.\r
1322\r
1323 When /P is in the String, the function stops at the first character that is not\r
1324 a valid decimal digit character after P is converted.\r
1325\r
36396ea2
RN
1326 If String is not aligned in a 16-bit boundary, then ASSERT().\r
1327\r
36396ea2
RN
1328 If EndPointer is not NULL and Address is translated from String, a pointer\r
1329 to the character that stopped the scan is stored at the location pointed to\r
1330 by EndPointer.\r
1331\r
1332 @param String Pointer to a Null-terminated Unicode string.\r
1333 @param EndPointer Pointer to character that stops scan.\r
1334 @param Address Pointer to the converted IPv4 address.\r
1335 @param PrefixLength Pointer to the converted IPv4 address prefix\r
1336 length. MAX_UINT8 is returned when /P is\r
1337 not in the String.\r
1338\r
1339 @retval RETURN_SUCCESS Address is translated from String.\r
1340 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1341 If Data is NULL.\r
1342 @retval RETURN_UNSUPPORTED If String is not in the correct format.\r
1343 If any decimal number converted from D\r
1344 exceeds 255.\r
1345 If the decimal number converted from P\r
1346 exceeds 32.\r
1347\r
1348**/\r
1349RETURN_STATUS\r
1350EFIAPI\r
1351StrToIpv4Address (\r
2f88bd3a
MK
1352 IN CONST CHAR16 *String,\r
1353 OUT CHAR16 **EndPointer OPTIONAL,\r
1354 OUT IPv4_ADDRESS *Address,\r
1355 OUT UINT8 *PrefixLength OPTIONAL\r
36396ea2
RN
1356 )\r
1357{\r
2f88bd3a
MK
1358 RETURN_STATUS Status;\r
1359 UINTN AddressIndex;\r
1360 UINTN Uintn;\r
1361 IPv4_ADDRESS LocalAddress;\r
1362 UINT8 LocalPrefixLength;\r
1363 CHAR16 *Pointer;\r
36396ea2
RN
1364\r
1365 LocalPrefixLength = MAX_UINT8;\r
1366\r
2f88bd3a 1367 ASSERT (((UINTN)String & BIT0) == 0);\r
36396ea2
RN
1368\r
1369 //\r
1370 // 1. None of String or Guid shall be a null pointer.\r
1371 //\r
1372 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1373 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);\r
1374\r
2f88bd3a 1375 for (Pointer = (CHAR16 *)String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {\r
36396ea2
RN
1376 if (!InternalIsDecimalDigitCharacter (*Pointer)) {\r
1377 //\r
1378 // D or P contains invalid characters.\r
1379 //\r
1380 break;\r
1381 }\r
1382\r
1383 //\r
1384 // Get D or P.\r
1385 //\r
2f88bd3a 1386 Status = StrDecimalToUintnS ((CONST CHAR16 *)Pointer, &Pointer, &Uintn);\r
36396ea2
RN
1387 if (RETURN_ERROR (Status)) {\r
1388 return RETURN_UNSUPPORTED;\r
1389 }\r
2f88bd3a 1390\r
36396ea2
RN
1391 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
1392 //\r
1393 // It's P.\r
1394 //\r
1395 if (Uintn > 32) {\r
1396 return RETURN_UNSUPPORTED;\r
1397 }\r
2f88bd3a
MK
1398\r
1399 LocalPrefixLength = (UINT8)Uintn;\r
36396ea2
RN
1400 } else {\r
1401 //\r
1402 // It's D.\r
1403 //\r
1404 if (Uintn > MAX_UINT8) {\r
1405 return RETURN_UNSUPPORTED;\r
1406 }\r
2f88bd3a
MK
1407\r
1408 LocalAddress.Addr[AddressIndex] = (UINT8)Uintn;\r
36396ea2
RN
1409 AddressIndex++;\r
1410 }\r
1411\r
1412 //\r
1413 // Check the '.' or '/', depending on the AddressIndex.\r
1414 //\r
1415 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
1416 if (*Pointer == L'/') {\r
1417 //\r
1418 // '/P' is in the String.\r
1419 // Skip "/" and get P in next loop.\r
1420 //\r
1421 Pointer++;\r
1422 } else {\r
1423 //\r
1424 // '/P' is not in the String.\r
1425 //\r
1426 break;\r
1427 }\r
1428 } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {\r
1429 if (*Pointer == L'.') {\r
1430 //\r
1431 // D should be followed by '.'\r
1432 //\r
1433 Pointer++;\r
1434 } else {\r
1435 return RETURN_UNSUPPORTED;\r
1436 }\r
1437 }\r
1438 }\r
1439\r
1440 if (AddressIndex < ARRAY_SIZE (Address->Addr)) {\r
1441 return RETURN_UNSUPPORTED;\r
1442 }\r
1443\r
1444 CopyMem (Address, &LocalAddress, sizeof (*Address));\r
1445 if (PrefixLength != NULL) {\r
1446 *PrefixLength = LocalPrefixLength;\r
1447 }\r
2f88bd3a 1448\r
36396ea2
RN
1449 if (EndPointer != NULL) {\r
1450 *EndPointer = Pointer;\r
1451 }\r
1452\r
1453 return RETURN_SUCCESS;\r
1454}\r
1455\r
1456/**\r
1457 Convert a Null-terminated Unicode GUID string to a value of type\r
1458 EFI_GUID.\r
1459\r
1460 This function outputs a GUID value by interpreting the contents of\r
1461 the Unicode string specified by String. The format of the input\r
1462 Unicode string String consists of 36 characters, as follows:\r
1463\r
1464 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp\r
1465\r
1466 The pairs aa - pp are two characters in the range [0-9], [a-f] and\r
1467 [A-F], with each pair representing a single byte hexadecimal value.\r
1468\r
1469 The mapping between String and the EFI_GUID structure is as follows:\r
1470 aa Data1[24:31]\r
1471 bb Data1[16:23]\r
1472 cc Data1[8:15]\r
1473 dd Data1[0:7]\r
1474 ee Data2[8:15]\r
1475 ff Data2[0:7]\r
1476 gg Data3[8:15]\r
1477 hh Data3[0:7]\r
1478 ii Data4[0:7]\r
1479 jj Data4[8:15]\r
1480 kk Data4[16:23]\r
1481 ll Data4[24:31]\r
1482 mm Data4[32:39]\r
1483 nn Data4[40:47]\r
1484 oo Data4[48:55]\r
1485 pp Data4[56:63]\r
1486\r
36396ea2
RN
1487 If String is not aligned in a 16-bit boundary, then ASSERT().\r
1488\r
1489 @param String Pointer to a Null-terminated Unicode string.\r
1490 @param Guid Pointer to the converted GUID.\r
1491\r
1492 @retval RETURN_SUCCESS Guid is translated from String.\r
1493 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1494 If Data is NULL.\r
1495 @retval RETURN_UNSUPPORTED If String is not as the above format.\r
1496\r
1497**/\r
1498RETURN_STATUS\r
1499EFIAPI\r
1500StrToGuid (\r
2f88bd3a
MK
1501 IN CONST CHAR16 *String,\r
1502 OUT GUID *Guid\r
36396ea2
RN
1503 )\r
1504{\r
2f88bd3a
MK
1505 RETURN_STATUS Status;\r
1506 GUID LocalGuid;\r
36396ea2 1507\r
2f88bd3a 1508 ASSERT (((UINTN)String & BIT0) == 0);\r
36396ea2
RN
1509\r
1510 //\r
1511 // 1. None of String or Guid shall be a null pointer.\r
1512 //\r
1513 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1514 SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);\r
1515\r
1516 //\r
1517 // Get aabbccdd in big-endian.\r
1518 //\r
2f88bd3a
MK
1519 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *)&LocalGuid.Data1, sizeof (LocalGuid.Data1));\r
1520 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data1)] != L'-')) {\r
36396ea2
RN
1521 return RETURN_UNSUPPORTED;\r
1522 }\r
2f88bd3a 1523\r
36396ea2
RN
1524 //\r
1525 // Convert big-endian to little-endian.\r
1526 //\r
1527 LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);\r
2f88bd3a 1528 String += 2 * sizeof (LocalGuid.Data1) + 1;\r
36396ea2
RN
1529\r
1530 //\r
1531 // Get eeff in big-endian.\r
1532 //\r
2f88bd3a
MK
1533 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *)&LocalGuid.Data2, sizeof (LocalGuid.Data2));\r
1534 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data2)] != L'-')) {\r
36396ea2
RN
1535 return RETURN_UNSUPPORTED;\r
1536 }\r
2f88bd3a 1537\r
36396ea2
RN
1538 //\r
1539 // Convert big-endian to little-endian.\r
1540 //\r
1541 LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);\r
2f88bd3a 1542 String += 2 * sizeof (LocalGuid.Data2) + 1;\r
36396ea2
RN
1543\r
1544 //\r
1545 // Get gghh in big-endian.\r
1546 //\r
2f88bd3a
MK
1547 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *)&LocalGuid.Data3, sizeof (LocalGuid.Data3));\r
1548 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data3)] != L'-')) {\r
36396ea2
RN
1549 return RETURN_UNSUPPORTED;\r
1550 }\r
2f88bd3a 1551\r
36396ea2
RN
1552 //\r
1553 // Convert big-endian to little-endian.\r
1554 //\r
1555 LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);\r
2f88bd3a 1556 String += 2 * sizeof (LocalGuid.Data3) + 1;\r
36396ea2
RN
1557\r
1558 //\r
1559 // Get iijj.\r
1560 //\r
1561 Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);\r
2f88bd3a 1562 if (RETURN_ERROR (Status) || (String[2 * 2] != L'-')) {\r
36396ea2
RN
1563 return RETURN_UNSUPPORTED;\r
1564 }\r
2f88bd3a 1565\r
36396ea2
RN
1566 String += 2 * 2 + 1;\r
1567\r
1568 //\r
1569 // Get kkllmmnnoopp.\r
1570 //\r
1571 Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);\r
1572 if (RETURN_ERROR (Status)) {\r
1573 return RETURN_UNSUPPORTED;\r
1574 }\r
1575\r
1576 CopyGuid (Guid, &LocalGuid);\r
1577 return RETURN_SUCCESS;\r
1578}\r
1579\r
1580/**\r
1581 Convert a Null-terminated Unicode hexadecimal string to a byte array.\r
1582\r
1583 This function outputs a byte array by interpreting the contents of\r
1584 the Unicode string specified by String in hexadecimal format. The format of\r
1585 the input Unicode string String is:\r
1586\r
1587 [XX]*\r
1588\r
1589 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].\r
1590 The function decodes every two hexadecimal digit characters as one byte. The\r
1591 decoding stops after Length of characters and outputs Buffer containing\r
1592 (Length / 2) bytes.\r
1593\r
1594 If String is not aligned in a 16-bit boundary, then ASSERT().\r
1595\r
36396ea2
RN
1596 @param String Pointer to a Null-terminated Unicode string.\r
1597 @param Length The number of Unicode characters to decode.\r
1598 @param Buffer Pointer to the converted bytes array.\r
1599 @param MaxBufferSize The maximum size of Buffer.\r
1600\r
1601 @retval RETURN_SUCCESS Buffer is translated from String.\r
1602 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1603 If Data is NULL.\r
1604 If Length is not multiple of 2.\r
1605 If PcdMaximumUnicodeStringLength is not zero,\r
1606 and Length is greater than\r
1607 PcdMaximumUnicodeStringLength.\r
1608 @retval RETURN_UNSUPPORTED If Length of characters from String contain\r
1609 a character that is not valid hexadecimal\r
1610 digit characters, or a Null-terminator.\r
1611 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).\r
1612**/\r
1613RETURN_STATUS\r
1614EFIAPI\r
1615StrHexToBytes (\r
2f88bd3a
MK
1616 IN CONST CHAR16 *String,\r
1617 IN UINTN Length,\r
1618 OUT UINT8 *Buffer,\r
1619 IN UINTN MaxBufferSize\r
36396ea2
RN
1620 )\r
1621{\r
2f88bd3a 1622 UINTN Index;\r
36396ea2 1623\r
2f88bd3a 1624 ASSERT (((UINTN)String & BIT0) == 0);\r
36396ea2
RN
1625\r
1626 //\r
1627 // 1. None of String or Buffer shall be a null pointer.\r
1628 //\r
1629 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1630 SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);\r
1631\r
1632 //\r
1633 // 2. Length shall not be greater than RSIZE_MAX.\r
1634 //\r
1635 if (RSIZE_MAX != 0) {\r
1636 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1637 }\r
1638\r
1639 //\r
1640 // 3. Length shall not be odd.\r
1641 //\r
1642 SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);\r
1643\r
1644 //\r
1645 // 4. MaxBufferSize shall equal to or greater than Length / 2.\r
1646 //\r
1647 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);\r
1648\r
1649 //\r
1650 // 5. String shall not contains invalid hexadecimal digits.\r
1651 //\r
1652 for (Index = 0; Index < Length; Index++) {\r
1653 if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {\r
1654 break;\r
1655 }\r
1656 }\r
2f88bd3a 1657\r
36396ea2
RN
1658 if (Index != Length) {\r
1659 return RETURN_UNSUPPORTED;\r
1660 }\r
1661\r
1662 //\r
1663 // Convert the hex string to bytes.\r
1664 //\r
2f88bd3a 1665 for (Index = 0; Index < Length; Index++) {\r
36396ea2
RN
1666 //\r
1667 // For even characters, write the upper nibble for each buffer byte,\r
1668 // and for even characters, the lower nibble.\r
1669 //\r
1670 if ((Index & BIT0) == 0) {\r
2f88bd3a 1671 Buffer[Index / 2] = (UINT8)InternalHexCharToUintn (String[Index]) << 4;\r
36396ea2 1672 } else {\r
2f88bd3a 1673 Buffer[Index / 2] |= (UINT8)InternalHexCharToUintn (String[Index]);\r
36396ea2
RN
1674 }\r
1675 }\r
2f88bd3a 1676\r
36396ea2
RN
1677 return RETURN_SUCCESS;\r
1678}\r
1679\r
c058d59f
JY
1680/**\r
1681 Returns the length of a Null-terminated Ascii string.\r
1682\r
328f84b1
JY
1683 This function is similar as strlen_s defined in C11.\r
1684\r
c058d59f
JY
1685 @param String A pointer to a Null-terminated Ascii string.\r
1686 @param MaxSize The maximum number of Destination Ascii\r
1687 char, including terminating null char.\r
1688\r
1689 @retval 0 If String is NULL.\r
1690 @retval MaxSize If there is no null character in the first MaxSize characters of String.\r
1691 @return The number of characters that percede the terminating null character.\r
1692\r
1693**/\r
1694UINTN\r
1695EFIAPI\r
1696AsciiStrnLenS (\r
2f88bd3a
MK
1697 IN CONST CHAR8 *String,\r
1698 IN UINTN MaxSize\r
c058d59f
JY
1699 )\r
1700{\r
2f88bd3a 1701 UINTN Length;\r
c058d59f
JY
1702\r
1703 //\r
cb867499 1704 // If String is a null pointer or MaxSize is 0, then the AsciiStrnLenS function returns zero.\r
c058d59f 1705 //\r
cb867499 1706 if ((String == NULL) || (MaxSize == 0)) {\r
c058d59f
JY
1707 return 0;\r
1708 }\r
1709\r
1710 //\r
1711 // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the\r
1712 // terminating null character. If there is no null character in the first MaxSize characters of\r
1713 // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall\r
1714 // be accessed by AsciiStrnLenS.\r
1715 //\r
c07c517c
HW
1716 Length = 0;\r
1717 while (String[Length] != 0) {\r
1718 if (Length >= MaxSize - 1) {\r
1719 return MaxSize;\r
1720 }\r
2f88bd3a 1721\r
c07c517c 1722 Length++;\r
c058d59f 1723 }\r
2f88bd3a 1724\r
c058d59f
JY
1725 return Length;\r
1726}\r
1727\r
b590e43a
HW
1728/**\r
1729 Returns the size of a Null-terminated Ascii string in bytes, including the\r
1730 Null terminator.\r
1731\r
1732 This function returns the size of the Null-terminated Ascii string specified\r
1733 by String in bytes, including the Null terminator.\r
1734\r
1735 @param String A pointer to a Null-terminated Ascii string.\r
1736 @param MaxSize The maximum number of Destination Ascii\r
1737 char, including the Null terminator.\r
1738\r
1739 @retval 0 If String is NULL.\r
1740 @retval (sizeof (CHAR8) * (MaxSize + 1))\r
1741 If there is no Null terminator in the first MaxSize characters of\r
1742 String.\r
1743 @return The size of the Null-terminated Ascii string in bytes, including the\r
1744 Null terminator.\r
1745\r
1746**/\r
1747UINTN\r
1748EFIAPI\r
1749AsciiStrnSizeS (\r
2f88bd3a
MK
1750 IN CONST CHAR8 *String,\r
1751 IN UINTN MaxSize\r
b590e43a
HW
1752 )\r
1753{\r
1754 //\r
1755 // If String is a null pointer, then the AsciiStrnSizeS function returns\r
1756 // zero.\r
1757 //\r
1758 if (String == NULL) {\r
1759 return 0;\r
1760 }\r
1761\r
1762 //\r
1763 // Otherwise, the AsciiStrnSizeS function returns the size of the\r
1764 // Null-terminated Ascii string in bytes, including the Null terminator. If\r
1765 // there is no Null terminator in the first MaxSize characters of String,\r
1766 // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a\r
1767 // consistent map with the AsciiStrnLenS function.\r
1768 //\r
1769 return (AsciiStrnLenS (String, MaxSize) + 1) * sizeof (*String);\r
1770}\r
1771\r
c058d59f
JY
1772/**\r
1773 Copies the string pointed to by Source (including the terminating null char)\r
1774 to the array pointed to by Destination.\r
1775\r
328f84b1
JY
1776 This function is similar as strcpy_s defined in C11.\r
1777\r
328f84b1
JY
1778 If an error is returned, then the Destination is unmodified.\r
1779\r
c058d59f
JY
1780 @param Destination A pointer to a Null-terminated Ascii string.\r
1781 @param DestMax The maximum number of Destination Ascii\r
1782 char, including terminating null char.\r
1783 @param Source A pointer to a Null-terminated Ascii string.\r
1784\r
1785 @retval RETURN_SUCCESS String is copied.\r
1786 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
1787 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
1788 If Source is NULL.\r
1789 If PcdMaximumAsciiStringLength is not zero,\r
973f8862 1790 and DestMax is greater than\r
c058d59f
JY
1791 PcdMaximumAsciiStringLength.\r
1792 If DestMax is 0.\r
1793 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
1794**/\r
1795RETURN_STATUS\r
1796EFIAPI\r
1797AsciiStrCpyS (\r
1798 OUT CHAR8 *Destination,\r
1799 IN UINTN DestMax,\r
1800 IN CONST CHAR8 *Source\r
1801 )\r
1802{\r
2f88bd3a 1803 UINTN SourceLen;\r
973f8862 1804\r
c058d59f
JY
1805 //\r
1806 // 1. Neither Destination nor Source shall be a null pointer.\r
1807 //\r
1808 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
1809 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
1810\r
1811 //\r
1812 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.\r
1813 //\r
1814 if (ASCII_RSIZE_MAX != 0) {\r
1815 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1816 }\r
1817\r
1818 //\r
1819 // 3. DestMax shall not equal zero.\r
1820 //\r
1821 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
1822\r
1823 //\r
1824 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
1825 //\r
1826 SourceLen = AsciiStrnLenS (Source, DestMax);\r
1827 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
1828\r
1829 //\r
1830 // 5. Copying shall not take place between objects that overlap.\r
1831 //\r
1832 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
1833\r
1834 //\r
1835 // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating\r
1836 // null character) into the array pointed to by Destination.\r
1837 //\r
1838 while (*Source != 0) {\r
1839 *(Destination++) = *(Source++);\r
1840 }\r
2f88bd3a 1841\r
c058d59f
JY
1842 *Destination = 0;\r
1843\r
1844 return RETURN_SUCCESS;\r
1845}\r
1846\r
1847/**\r
1848 Copies not more than Length successive char from the string pointed to by\r
1849 Source to the array pointed to by Destination. If no null char is copied from\r
1850 Source, then Destination[Length] is always set to null.\r
1851\r
328f84b1
JY
1852 This function is similar as strncpy_s defined in C11.\r
1853\r
328f84b1
JY
1854 If an error is returned, then the Destination is unmodified.\r
1855\r
c058d59f
JY
1856 @param Destination A pointer to a Null-terminated Ascii string.\r
1857 @param DestMax The maximum number of Destination Ascii\r
1858 char, including terminating null char.\r
1859 @param Source A pointer to a Null-terminated Ascii string.\r
1860 @param Length The maximum number of Ascii characters to copy.\r
1861\r
1862 @retval RETURN_SUCCESS String is copied.\r
973f8862 1863 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than\r
c058d59f
JY
1864 MIN(StrLen(Source), Length).\r
1865 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
1866 If Source is NULL.\r
1867 If PcdMaximumAsciiStringLength is not zero,\r
973f8862 1868 and DestMax is greater than\r
c058d59f
JY
1869 PcdMaximumAsciiStringLength.\r
1870 If DestMax is 0.\r
1871 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
1872**/\r
1873RETURN_STATUS\r
1874EFIAPI\r
1875AsciiStrnCpyS (\r
1876 OUT CHAR8 *Destination,\r
1877 IN UINTN DestMax,\r
1878 IN CONST CHAR8 *Source,\r
1879 IN UINTN Length\r
1880 )\r
1881{\r
2f88bd3a 1882 UINTN SourceLen;\r
c058d59f
JY
1883\r
1884 //\r
1885 // 1. Neither Destination nor Source shall be a null pointer.\r
1886 //\r
1887 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
1888 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
1889\r
1890 //\r
1891 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX\r
1892 //\r
1893 if (ASCII_RSIZE_MAX != 0) {\r
1894 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1895 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1896 }\r
1897\r
1898 //\r
1899 // 3. DestMax shall not equal zero.\r
1900 //\r
1901 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
1902\r
1903 //\r
1904 // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
1905 //\r
56658c22 1906 SourceLen = AsciiStrnLenS (Source, MIN (DestMax, Length));\r
c058d59f
JY
1907 if (Length >= DestMax) {\r
1908 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
1909 }\r
1910\r
1911 //\r
1912 // 5. Copying shall not take place between objects that overlap.\r
1913 //\r
1914 if (SourceLen > Length) {\r
1915 SourceLen = Length;\r
1916 }\r
2f88bd3a 1917\r
c058d59f
JY
1918 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
1919\r
1920 //\r
1921 // The AsciiStrnCpyS function copies not more than Length successive characters (characters that\r
1922 // follow a null character are not copied) from the array pointed to by Source to the array\r
1923 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null\r
1924 // character.\r
1925 //\r
56658c22 1926 while ((SourceLen > 0) && (*Source != 0)) {\r
c058d59f
JY
1927 *(Destination++) = *(Source++);\r
1928 SourceLen--;\r
1929 }\r
2f88bd3a 1930\r
c058d59f
JY
1931 *Destination = 0;\r
1932\r
1933 return RETURN_SUCCESS;\r
1934}\r
1935\r
1936/**\r
1937 Appends a copy of the string pointed to by Source (including the terminating\r
1938 null char) to the end of the string pointed to by Destination.\r
1939\r
328f84b1
JY
1940 This function is similar as strcat_s defined in C11.\r
1941\r
328f84b1
JY
1942 If an error is returned, then the Destination is unmodified.\r
1943\r
c058d59f
JY
1944 @param Destination A pointer to a Null-terminated Ascii string.\r
1945 @param DestMax The maximum number of Destination Ascii\r
1946 char, including terminating null char.\r
1947 @param Source A pointer to a Null-terminated Ascii string.\r
1948\r
1949 @retval RETURN_SUCCESS String is appended.\r
973f8862 1950 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than\r
c058d59f
JY
1951 StrLen(Destination).\r
1952 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
1953 greater than StrLen(Source).\r
1954 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
1955 If Source is NULL.\r
1956 If PcdMaximumAsciiStringLength is not zero,\r
973f8862 1957 and DestMax is greater than\r
c058d59f
JY
1958 PcdMaximumAsciiStringLength.\r
1959 If DestMax is 0.\r
1960 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
1961**/\r
1962RETURN_STATUS\r
1963EFIAPI\r
1964AsciiStrCatS (\r
1965 IN OUT CHAR8 *Destination,\r
1966 IN UINTN DestMax,\r
1967 IN CONST CHAR8 *Source\r
1968 )\r
1969{\r
2f88bd3a
MK
1970 UINTN DestLen;\r
1971 UINTN CopyLen;\r
1972 UINTN SourceLen;\r
973f8862 1973\r
c058d59f
JY
1974 //\r
1975 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.\r
1976 //\r
1977 DestLen = AsciiStrnLenS (Destination, DestMax);\r
1978 CopyLen = DestMax - DestLen;\r
1979\r
1980 //\r
1981 // 1. Neither Destination nor Source shall be a null pointer.\r
1982 //\r
1983 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
1984 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
1985\r
1986 //\r
1987 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.\r
1988 //\r
1989 if (ASCII_RSIZE_MAX != 0) {\r
1990 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1991 }\r
1992\r
1993 //\r
1994 // 3. DestMax shall not equal zero.\r
1995 //\r
1996 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
1997\r
1998 //\r
1999 // 4. CopyLen shall not equal zero.\r
2000 //\r
2001 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
2002\r
2003 //\r
2004 // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).\r
2005 //\r
2006 SourceLen = AsciiStrnLenS (Source, CopyLen);\r
2007 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2008\r
2009 //\r
2010 // 6. Copying shall not take place between objects that overlap.\r
2011 //\r
2012 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
2013\r
2014 //\r
2015 // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the\r
2016 // terminating null character) to the end of the string pointed to by Destination. The initial character\r
2017 // from Source overwrites the null character at the end of Destination.\r
2018 //\r
2019 Destination = Destination + DestLen;\r
2020 while (*Source != 0) {\r
2021 *(Destination++) = *(Source++);\r
2022 }\r
2f88bd3a 2023\r
c058d59f
JY
2024 *Destination = 0;\r
2025\r
2026 return RETURN_SUCCESS;\r
2027}\r
2028\r
2029/**\r
2030 Appends not more than Length successive char from the string pointed to by\r
2031 Source to the end of the string pointed to by Destination. If no null char is\r
2032 copied from Source, then Destination[StrLen(Destination) + Length] is always\r
2033 set to null.\r
2034\r
328f84b1
JY
2035 This function is similar as strncat_s defined in C11.\r
2036\r
328f84b1
JY
2037 If an error is returned, then the Destination is unmodified.\r
2038\r
c058d59f
JY
2039 @param Destination A pointer to a Null-terminated Ascii string.\r
2040 @param DestMax The maximum number of Destination Ascii\r
2041 char, including terminating null char.\r
2042 @param Source A pointer to a Null-terminated Ascii string.\r
2043 @param Length The maximum number of Ascii characters to copy.\r
2044\r
2045 @retval RETURN_SUCCESS String is appended.\r
2046 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than\r
2047 StrLen(Destination).\r
2048 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
2049 greater than MIN(StrLen(Source), Length).\r
2050 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2051 If Source is NULL.\r
2052 If PcdMaximumAsciiStringLength is not zero,\r
973f8862 2053 and DestMax is greater than\r
c058d59f
JY
2054 PcdMaximumAsciiStringLength.\r
2055 If DestMax is 0.\r
2056 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2057**/\r
2058RETURN_STATUS\r
2059EFIAPI\r
2060AsciiStrnCatS (\r
2061 IN OUT CHAR8 *Destination,\r
2062 IN UINTN DestMax,\r
2063 IN CONST CHAR8 *Source,\r
2064 IN UINTN Length\r
2065 )\r
2066{\r
2f88bd3a
MK
2067 UINTN DestLen;\r
2068 UINTN CopyLen;\r
2069 UINTN SourceLen;\r
973f8862 2070\r
c058d59f
JY
2071 //\r
2072 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.\r
2073 //\r
2074 DestLen = AsciiStrnLenS (Destination, DestMax);\r
2075 CopyLen = DestMax - DestLen;\r
2076\r
2077 //\r
2078 // 1. Neither Destination nor Source shall be a null pointer.\r
2079 //\r
2080 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2081 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2082\r
2083 //\r
2084 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.\r
2085 //\r
2086 if (ASCII_RSIZE_MAX != 0) {\r
2087 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2088 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2089 }\r
2090\r
2091 //\r
2092 // 3. DestMax shall not equal zero.\r
2093 //\r
2094 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2095\r
2096 //\r
2097 // 4. CopyLen shall not equal zero.\r
2098 //\r
2099 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
2100\r
2101 //\r
2102 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).\r
2103 //\r
56658c22 2104 SourceLen = AsciiStrnLenS (Source, MIN (CopyLen, Length));\r
c058d59f
JY
2105 if (Length >= CopyLen) {\r
2106 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2107 }\r
2108\r
2109 //\r
2110 // 6. Copying shall not take place between objects that overlap.\r
2111 //\r
2112 if (SourceLen > Length) {\r
2113 SourceLen = Length;\r
2114 }\r
2f88bd3a 2115\r
c058d59f
JY
2116 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
2117\r
2118 //\r
2119 // The AsciiStrnCatS function appends not more than Length successive characters (characters\r
2120 // that follow a null character are not copied) from the array pointed to by Source to the end of\r
2121 // the string pointed to by Destination. The initial character from Source overwrites the null character at\r
2122 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to\r
2123 // a null character.\r
2124 //\r
2125 Destination = Destination + DestLen;\r
56658c22 2126 while ((SourceLen > 0) && (*Source != 0)) {\r
c058d59f
JY
2127 *(Destination++) = *(Source++);\r
2128 SourceLen--;\r
2129 }\r
2f88bd3a 2130\r
c058d59f
JY
2131 *Destination = 0;\r
2132\r
d8af3301
HW
2133 return RETURN_SUCCESS;\r
2134}\r
2135\r
2136/**\r
2137 Convert a Null-terminated Ascii decimal string to a value of type UINTN.\r
2138\r
2139 This function outputs a value of type UINTN by interpreting the contents of\r
2140 the Ascii string specified by String as a decimal number. The format of the\r
2141 input Ascii string String is:\r
2142\r
2143 [spaces] [decimal digits].\r
2144\r
2145 The valid decimal digit character is in the range [0-9]. The function will\r
2146 ignore the pad space, which includes spaces or tab characters, before\r
2147 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
2148 be ignored. Then, the function stops at the first character that is a not a\r
2149 valid decimal character or a Null-terminator, whichever one comes first.\r
2150\r
d8af3301
HW
2151 If String has no valid decimal digits in the above format, then 0 is stored\r
2152 at the location pointed to by Data.\r
2153 If the number represented by String exceeds the range defined by UINTN, then\r
2154 MAX_UINTN is stored at the location pointed to by Data.\r
2155\r
2156 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
2157 is stored at the location pointed to by EndPointer. If String has no valid\r
2158 decimal digits right after the optional pad spaces, the value of String is\r
2159 stored at the location pointed to by EndPointer.\r
2160\r
2161 @param String Pointer to a Null-terminated Ascii string.\r
2162 @param EndPointer Pointer to character that stops scan.\r
2163 @param Data Pointer to the converted value.\r
2164\r
2165 @retval RETURN_SUCCESS Value is translated from String.\r
2166 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
2167 If Data is NULL.\r
2168 If PcdMaximumAsciiStringLength is not zero,\r
2169 and String contains more than\r
2170 PcdMaximumAsciiStringLength Ascii\r
2171 characters, not including the\r
2172 Null-terminator.\r
2173 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
2174 the range defined by UINTN.\r
2175\r
2176**/\r
2177RETURN_STATUS\r
2178EFIAPI\r
2179AsciiStrDecimalToUintnS (\r
2f88bd3a
MK
2180 IN CONST CHAR8 *String,\r
2181 OUT CHAR8 **EndPointer OPTIONAL,\r
2182 OUT UINTN *Data\r
d8af3301
HW
2183 )\r
2184{\r
2185 //\r
2186 // 1. Neither String nor Data shall be a null pointer.\r
2187 //\r
2188 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
2189 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
2190\r
2191 //\r
2192 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
2193 //\r
2194 if (ASCII_RSIZE_MAX != 0) {\r
2195 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2196 }\r
2197\r
2198 if (EndPointer != NULL) {\r
2f88bd3a 2199 *EndPointer = (CHAR8 *)String;\r
d8af3301
HW
2200 }\r
2201\r
2202 //\r
2203 // Ignore the pad spaces (space or tab)\r
2204 //\r
2205 while ((*String == ' ') || (*String == '\t')) {\r
2206 String++;\r
2207 }\r
2208\r
2209 //\r
2210 // Ignore leading Zeros after the spaces\r
2211 //\r
2212 while (*String == '0') {\r
2213 String++;\r
2214 }\r
2215\r
2216 *Data = 0;\r
2217\r
2218 while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
2219 //\r
2220 // If the number represented by String overflows according to the range\r
2221 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
2222 // RETURN_UNSUPPORTED is returned.\r
2223 //\r
2224 if (*Data > ((MAX_UINTN - (*String - '0')) / 10)) {\r
2225 *Data = MAX_UINTN;\r
2226 if (EndPointer != NULL) {\r
2f88bd3a 2227 *EndPointer = (CHAR8 *)String;\r
d8af3301 2228 }\r
2f88bd3a 2229\r
d8af3301
HW
2230 return RETURN_UNSUPPORTED;\r
2231 }\r
2232\r
2233 *Data = *Data * 10 + (*String - '0');\r
2234 String++;\r
2235 }\r
2236\r
2237 if (EndPointer != NULL) {\r
2f88bd3a 2238 *EndPointer = (CHAR8 *)String;\r
d8af3301 2239 }\r
2f88bd3a 2240\r
d8af3301
HW
2241 return RETURN_SUCCESS;\r
2242}\r
2243\r
2244/**\r
2245 Convert a Null-terminated Ascii decimal string to a value of type UINT64.\r
2246\r
2247 This function outputs a value of type UINT64 by interpreting the contents of\r
2248 the Ascii string specified by String as a decimal number. The format of the\r
2249 input Ascii string String is:\r
2250\r
2251 [spaces] [decimal digits].\r
2252\r
2253 The valid decimal digit character is in the range [0-9]. The function will\r
2254 ignore the pad space, which includes spaces or tab characters, before\r
2255 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
2256 be ignored. Then, the function stops at the first character that is a not a\r
2257 valid decimal character or a Null-terminator, whichever one comes first.\r
2258\r
d8af3301
HW
2259 If String has no valid decimal digits in the above format, then 0 is stored\r
2260 at the location pointed to by Data.\r
2261 If the number represented by String exceeds the range defined by UINT64, then\r
2262 MAX_UINT64 is stored at the location pointed to by Data.\r
2263\r
2264 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
2265 is stored at the location pointed to by EndPointer. If String has no valid\r
2266 decimal digits right after the optional pad spaces, the value of String is\r
2267 stored at the location pointed to by EndPointer.\r
2268\r
2269 @param String Pointer to a Null-terminated Ascii string.\r
2270 @param EndPointer Pointer to character that stops scan.\r
2271 @param Data Pointer to the converted value.\r
2272\r
2273 @retval RETURN_SUCCESS Value is translated from String.\r
2274 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
2275 If Data is NULL.\r
2276 If PcdMaximumAsciiStringLength is not zero,\r
2277 and String contains more than\r
2278 PcdMaximumAsciiStringLength Ascii\r
2279 characters, not including the\r
2280 Null-terminator.\r
2281 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
2282 the range defined by UINT64.\r
2283\r
2284**/\r
2285RETURN_STATUS\r
2286EFIAPI\r
2287AsciiStrDecimalToUint64S (\r
2f88bd3a
MK
2288 IN CONST CHAR8 *String,\r
2289 OUT CHAR8 **EndPointer OPTIONAL,\r
2290 OUT UINT64 *Data\r
d8af3301
HW
2291 )\r
2292{\r
2293 //\r
2294 // 1. Neither String nor Data shall be a null pointer.\r
2295 //\r
2296 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
2297 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
2298\r
2299 //\r
2300 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
2301 //\r
2302 if (ASCII_RSIZE_MAX != 0) {\r
2303 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2304 }\r
2305\r
2306 if (EndPointer != NULL) {\r
2f88bd3a 2307 *EndPointer = (CHAR8 *)String;\r
d8af3301
HW
2308 }\r
2309\r
2310 //\r
2311 // Ignore the pad spaces (space or tab)\r
2312 //\r
2313 while ((*String == ' ') || (*String == '\t')) {\r
2314 String++;\r
2315 }\r
2316\r
2317 //\r
2318 // Ignore leading Zeros after the spaces\r
2319 //\r
2320 while (*String == '0') {\r
2321 String++;\r
2322 }\r
2323\r
2324 *Data = 0;\r
2325\r
2326 while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
2327 //\r
2328 // If the number represented by String overflows according to the range\r
2329 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
2330 // RETURN_UNSUPPORTED is returned.\r
2331 //\r
2332 if (*Data > DivU64x32 (MAX_UINT64 - (*String - '0'), 10)) {\r
2333 *Data = MAX_UINT64;\r
2334 if (EndPointer != NULL) {\r
2f88bd3a 2335 *EndPointer = (CHAR8 *)String;\r
d8af3301 2336 }\r
2f88bd3a 2337\r
d8af3301
HW
2338 return RETURN_UNSUPPORTED;\r
2339 }\r
2340\r
2341 *Data = MultU64x32 (*Data, 10) + (*String - '0');\r
2342 String++;\r
2343 }\r
2344\r
2345 if (EndPointer != NULL) {\r
2f88bd3a 2346 *EndPointer = (CHAR8 *)String;\r
d8af3301 2347 }\r
2f88bd3a 2348\r
d8af3301
HW
2349 return RETURN_SUCCESS;\r
2350}\r
2351\r
2352/**\r
2353 Convert a Null-terminated Ascii hexadecimal string to a value of type UINTN.\r
2354\r
2355 This function outputs a value of type UINTN by interpreting the contents of\r
2356 the Ascii string specified by String as a hexadecimal number. The format of\r
2357 the input Ascii string String is:\r
2358\r
2359 [spaces][zeros][x][hexadecimal digits].\r
2360\r
2361 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
2362 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If\r
2363 "x" appears in the input string, it must be prefixed with at least one 0. The\r
2364 function will ignore the pad space, which includes spaces or tab characters,\r
2365 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or\r
2366 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or\r
2367 the first valid hexadecimal digit. Then, the function stops at the first\r
2368 character that is a not a valid hexadecimal character or Null-terminator,\r
2369 whichever on comes first.\r
2370\r
d8af3301
HW
2371 If String has no valid hexadecimal digits in the above format, then 0 is\r
2372 stored at the location pointed to by Data.\r
2373 If the number represented by String exceeds the range defined by UINTN, then\r
2374 MAX_UINTN is stored at the location pointed to by Data.\r
2375\r
2376 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
2377 is stored at the location pointed to by EndPointer. If String has no valid\r
2378 hexadecimal digits right after the optional pad spaces, the value of String\r
2379 is stored at the location pointed to by EndPointer.\r
2380\r
2381 @param String Pointer to a Null-terminated Ascii string.\r
2382 @param EndPointer Pointer to character that stops scan.\r
2383 @param Data Pointer to the converted value.\r
2384\r
2385 @retval RETURN_SUCCESS Value is translated from String.\r
2386 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
2387 If Data is NULL.\r
2388 If PcdMaximumAsciiStringLength is not zero,\r
2389 and String contains more than\r
2390 PcdMaximumAsciiStringLength Ascii\r
2391 characters, not including the\r
2392 Null-terminator.\r
2393 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
2394 the range defined by UINTN.\r
2395\r
2396**/\r
2397RETURN_STATUS\r
2398EFIAPI\r
2399AsciiStrHexToUintnS (\r
2f88bd3a
MK
2400 IN CONST CHAR8 *String,\r
2401 OUT CHAR8 **EndPointer OPTIONAL,\r
2402 OUT UINTN *Data\r
d8af3301
HW
2403 )\r
2404{\r
35043a5e
PF
2405 BOOLEAN FoundLeadingZero;\r
2406\r
2407 FoundLeadingZero = FALSE;\r
d8af3301
HW
2408 //\r
2409 // 1. Neither String nor Data shall be a null pointer.\r
2410 //\r
2411 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
2412 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
2413\r
2414 //\r
2415 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
2416 //\r
2417 if (ASCII_RSIZE_MAX != 0) {\r
2418 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2419 }\r
2420\r
2421 if (EndPointer != NULL) {\r
2f88bd3a 2422 *EndPointer = (CHAR8 *)String;\r
d8af3301
HW
2423 }\r
2424\r
2425 //\r
2426 // Ignore the pad spaces (space or tab)\r
2427 //\r
2428 while ((*String == ' ') || (*String == '\t')) {\r
2429 String++;\r
2430 }\r
2431\r
2432 //\r
2433 // Ignore leading Zeros after the spaces\r
2434 //\r
35043a5e 2435 FoundLeadingZero = *String == '0';\r
d8af3301
HW
2436 while (*String == '0') {\r
2437 String++;\r
2438 }\r
2439\r
5dbfa01e 2440 if (AsciiCharToUpper (*String) == 'X') {\r
35043a5e 2441 if (!FoundLeadingZero) {\r
d8af3301
HW
2442 *Data = 0;\r
2443 return RETURN_SUCCESS;\r
2444 }\r
2f88bd3a 2445\r
d8af3301
HW
2446 //\r
2447 // Skip the 'X'\r
2448 //\r
2449 String++;\r
2450 }\r
2451\r
2452 *Data = 0;\r
2453\r
2454 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
2455 //\r
2456 // If the number represented by String overflows according to the range\r
2457 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
2458 // RETURN_UNSUPPORTED is returned.\r
2459 //\r
2460 if (*Data > ((MAX_UINTN - InternalAsciiHexCharToUintn (*String)) >> 4)) {\r
2461 *Data = MAX_UINTN;\r
2462 if (EndPointer != NULL) {\r
2f88bd3a 2463 *EndPointer = (CHAR8 *)String;\r
d8af3301 2464 }\r
2f88bd3a 2465\r
d8af3301
HW
2466 return RETURN_UNSUPPORTED;\r
2467 }\r
2468\r
2469 *Data = (*Data << 4) + InternalAsciiHexCharToUintn (*String);\r
2470 String++;\r
2471 }\r
2472\r
2473 if (EndPointer != NULL) {\r
2f88bd3a 2474 *EndPointer = (CHAR8 *)String;\r
d8af3301 2475 }\r
2f88bd3a 2476\r
d8af3301
HW
2477 return RETURN_SUCCESS;\r
2478}\r
2479\r
2480/**\r
2481 Convert a Null-terminated Ascii hexadecimal string to a value of type UINT64.\r
2482\r
2483 This function outputs a value of type UINT64 by interpreting the contents of\r
2484 the Ascii string specified by String as a hexadecimal number. The format of\r
2485 the input Ascii string String is:\r
2486\r
2487 [spaces][zeros][x][hexadecimal digits].\r
2488\r
2489 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
2490 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If\r
2491 "x" appears in the input string, it must be prefixed with at least one 0. The\r
2492 function will ignore the pad space, which includes spaces or tab characters,\r
2493 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or\r
2494 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or\r
2495 the first valid hexadecimal digit. Then, the function stops at the first\r
2496 character that is a not a valid hexadecimal character or Null-terminator,\r
2497 whichever on comes first.\r
2498\r
d8af3301
HW
2499 If String has no valid hexadecimal digits in the above format, then 0 is\r
2500 stored at the location pointed to by Data.\r
2501 If the number represented by String exceeds the range defined by UINT64, then\r
2502 MAX_UINT64 is stored at the location pointed to by Data.\r
2503\r
2504 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
2505 is stored at the location pointed to by EndPointer. If String has no valid\r
2506 hexadecimal digits right after the optional pad spaces, the value of String\r
2507 is stored at the location pointed to by EndPointer.\r
2508\r
2509 @param String Pointer to a Null-terminated Ascii string.\r
2510 @param EndPointer Pointer to character that stops scan.\r
2511 @param Data Pointer to the converted value.\r
2512\r
2513 @retval RETURN_SUCCESS Value is translated from String.\r
2514 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
2515 If Data is NULL.\r
2516 If PcdMaximumAsciiStringLength is not zero,\r
2517 and String contains more than\r
2518 PcdMaximumAsciiStringLength Ascii\r
2519 characters, not including the\r
2520 Null-terminator.\r
2521 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
2522 the range defined by UINT64.\r
2523\r
2524**/\r
2525RETURN_STATUS\r
2526EFIAPI\r
2527AsciiStrHexToUint64S (\r
2f88bd3a
MK
2528 IN CONST CHAR8 *String,\r
2529 OUT CHAR8 **EndPointer OPTIONAL,\r
2530 OUT UINT64 *Data\r
d8af3301
HW
2531 )\r
2532{\r
35043a5e
PF
2533 BOOLEAN FoundLeadingZero;\r
2534\r
2535 FoundLeadingZero = FALSE;\r
d8af3301
HW
2536 //\r
2537 // 1. Neither String nor Data shall be a null pointer.\r
2538 //\r
2539 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
2540 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
2541\r
2542 //\r
2543 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
2544 //\r
2545 if (ASCII_RSIZE_MAX != 0) {\r
2546 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2547 }\r
2548\r
2549 if (EndPointer != NULL) {\r
2f88bd3a 2550 *EndPointer = (CHAR8 *)String;\r
d8af3301
HW
2551 }\r
2552\r
2553 //\r
2554 // Ignore the pad spaces (space or tab)\r
2555 //\r
2556 while ((*String == ' ') || (*String == '\t')) {\r
2557 String++;\r
2558 }\r
2559\r
2560 //\r
2561 // Ignore leading Zeros after the spaces\r
2562 //\r
35043a5e 2563 FoundLeadingZero = *String == '0';\r
d8af3301
HW
2564 while (*String == '0') {\r
2565 String++;\r
2566 }\r
2567\r
5dbfa01e 2568 if (AsciiCharToUpper (*String) == 'X') {\r
35043a5e 2569 if (!FoundLeadingZero) {\r
d8af3301
HW
2570 *Data = 0;\r
2571 return RETURN_SUCCESS;\r
2572 }\r
2f88bd3a 2573\r
d8af3301
HW
2574 //\r
2575 // Skip the 'X'\r
2576 //\r
2577 String++;\r
2578 }\r
2579\r
2580 *Data = 0;\r
2581\r
2582 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
2583 //\r
2584 // If the number represented by String overflows according to the range\r
2585 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
2586 // RETURN_UNSUPPORTED is returned.\r
2587 //\r
2588 if (*Data > RShiftU64 (MAX_UINT64 - InternalAsciiHexCharToUintn (*String), 4)) {\r
2589 *Data = MAX_UINT64;\r
2590 if (EndPointer != NULL) {\r
2f88bd3a 2591 *EndPointer = (CHAR8 *)String;\r
d8af3301 2592 }\r
2f88bd3a 2593\r
d8af3301
HW
2594 return RETURN_UNSUPPORTED;\r
2595 }\r
2596\r
2597 *Data = LShiftU64 (*Data, 4) + InternalAsciiHexCharToUintn (*String);\r
2598 String++;\r
2599 }\r
2600\r
2601 if (EndPointer != NULL) {\r
2f88bd3a 2602 *EndPointer = (CHAR8 *)String;\r
d8af3301 2603 }\r
2f88bd3a 2604\r
c058d59f
JY
2605 return RETURN_SUCCESS;\r
2606}\r
3ab41b7a
JY
2607\r
2608/**\r
2609 Convert a Null-terminated Unicode string to a Null-terminated\r
2610 ASCII string.\r
2611\r
2612 This function is similar to AsciiStrCpyS.\r
2613\r
2614 This function converts the content of the Unicode string Source\r
2615 to the ASCII string Destination by copying the lower 8 bits of\r
2616 each Unicode character. The function terminates the ASCII string\r
2617 Destination by appending a Null-terminator character at the end.\r
2618\r
2619 The caller is responsible to make sure Destination points to a buffer with size\r
2620 equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.\r
2621\r
2622 If any Unicode characters in Source contain non-zero value in\r
2623 the upper 8 bits, then ASSERT().\r
2624\r
2625 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
3ab41b7a
JY
2626\r
2627 If an error is returned, then the Destination is unmodified.\r
2628\r
2629 @param Source The pointer to a Null-terminated Unicode string.\r
2630 @param Destination The pointer to a Null-terminated ASCII string.\r
2631 @param DestMax The maximum number of Destination Ascii\r
2632 char, including terminating null char.\r
2633\r
2634 @retval RETURN_SUCCESS String is converted.\r
2635 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
2636 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2637 If Source is NULL.\r
2638 If PcdMaximumAsciiStringLength is not zero,\r
2639 and DestMax is greater than\r
2640 PcdMaximumAsciiStringLength.\r
2641 If PcdMaximumUnicodeStringLength is not zero,\r
2642 and DestMax is greater than\r
2643 PcdMaximumUnicodeStringLength.\r
2644 If DestMax is 0.\r
2645 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2646\r
2647**/\r
2648RETURN_STATUS\r
2649EFIAPI\r
2650UnicodeStrToAsciiStrS (\r
2f88bd3a
MK
2651 IN CONST CHAR16 *Source,\r
2652 OUT CHAR8 *Destination,\r
2653 IN UINTN DestMax\r
3ab41b7a
JY
2654 )\r
2655{\r
2f88bd3a 2656 UINTN SourceLen;\r
3ab41b7a 2657\r
2f88bd3a 2658 ASSERT (((UINTN)Source & BIT0) == 0);\r
3ab41b7a
JY
2659\r
2660 //\r
2661 // 1. Neither Destination nor Source shall be a null pointer.\r
2662 //\r
2663 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2664 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2665\r
2666 //\r
2667 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.\r
2668 //\r
2669 if (ASCII_RSIZE_MAX != 0) {\r
2670 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2671 }\r
2f88bd3a 2672\r
3ab41b7a
JY
2673 if (RSIZE_MAX != 0) {\r
2674 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2675 }\r
2676\r
2677 //\r
2678 // 3. DestMax shall not equal zero.\r
2679 //\r
2680 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2681\r
2682 //\r
2683 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).\r
2684 //\r
2685 SourceLen = StrnLenS (Source, DestMax);\r
2686 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2687\r
2688 //\r
2689 // 5. Copying shall not take place between objects that overlap.\r
2690 //\r
2f88bd3a 2691 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof (CHAR16)), RETURN_ACCESS_DENIED);\r
3ab41b7a
JY
2692\r
2693 //\r
2694 // convert string\r
2695 //\r
2696 while (*Source != '\0') {\r
2697 //\r
2698 // If any Unicode characters in Source contain\r
2699 // non-zero value in the upper 8 bits, then ASSERT().\r
2700 //\r
2701 ASSERT (*Source < 0x100);\r
2f88bd3a 2702 *(Destination++) = (CHAR8)*(Source++);\r
3ab41b7a 2703 }\r
2f88bd3a 2704\r
3ab41b7a
JY
2705 *Destination = '\0';\r
2706\r
2707 return RETURN_SUCCESS;\r
2708}\r
2709\r
02263214
HW
2710/**\r
2711 Convert not more than Length successive characters from a Null-terminated\r
2712 Unicode string to a Null-terminated Ascii string. If no null char is copied\r
2713 from Source, then Destination[Length] is always set to null.\r
2714\r
2715 This function converts not more than Length successive characters from the\r
2716 Unicode string Source to the Ascii string Destination by copying the lower 8\r
2717 bits of each Unicode character. The function terminates the Ascii string\r
2718 Destination by appending a Null-terminator character at the end.\r
2719\r
2720 The caller is responsible to make sure Destination points to a buffer with\r
2721 size not smaller than ((MIN(StrLen(Source), Length) + 1) * sizeof (CHAR8))\r
2722 in bytes.\r
2723\r
2724 If any Unicode characters in Source contain non-zero value in the upper 8\r
2725 bits, then ASSERT().\r
2726 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
02263214
HW
2727\r
2728 If an error is returned, then Destination and DestinationLength are\r
2729 unmodified.\r
2730\r
2731 @param Source The pointer to a Null-terminated Unicode string.\r
2732 @param Length The maximum number of Unicode characters to\r
2733 convert.\r
2734 @param Destination The pointer to a Null-terminated Ascii string.\r
2735 @param DestMax The maximum number of Destination Ascii char,\r
2736 including terminating null char.\r
2737 @param DestinationLength The number of Unicode characters converted.\r
2738\r
2739 @retval RETURN_SUCCESS String is converted.\r
2740 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2741 If Source is NULL.\r
2742 If DestinationLength is NULL.\r
2743 If PcdMaximumAsciiStringLength is not zero,\r
2744 and Length or DestMax is greater than\r
2745 PcdMaximumAsciiStringLength.\r
2746 If PcdMaximumUnicodeStringLength is not\r
2747 zero, and Length or DestMax is greater than\r
2748 PcdMaximumUnicodeStringLength.\r
2749 If DestMax is 0.\r
2750 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than\r
2751 MIN(StrLen(Source), Length).\r
2752 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2753\r
2754**/\r
2755RETURN_STATUS\r
2756EFIAPI\r
2757UnicodeStrnToAsciiStrS (\r
2f88bd3a
MK
2758 IN CONST CHAR16 *Source,\r
2759 IN UINTN Length,\r
2760 OUT CHAR8 *Destination,\r
2761 IN UINTN DestMax,\r
2762 OUT UINTN *DestinationLength\r
02263214
HW
2763 )\r
2764{\r
2f88bd3a 2765 UINTN SourceLen;\r
02263214 2766\r
2f88bd3a 2767 ASSERT (((UINTN)Source & BIT0) == 0);\r
02263214
HW
2768\r
2769 //\r
2770 // 1. None of Destination, Source or DestinationLength shall be a null\r
2771 // pointer.\r
2772 //\r
2773 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2774 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2775 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);\r
2776\r
2777 //\r
2778 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or\r
2779 // RSIZE_MAX.\r
2780 //\r
2781 if (ASCII_RSIZE_MAX != 0) {\r
2782 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2783 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2784 }\r
2f88bd3a 2785\r
02263214
HW
2786 if (RSIZE_MAX != 0) {\r
2787 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2788 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2789 }\r
2790\r
2791 //\r
2792 // 3. DestMax shall not equal zero.\r
2793 //\r
2794 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2795\r
2796 //\r
2797 // 4. If Length is not less than DestMax, then DestMax shall be greater than\r
2798 // StrnLenS(Source, DestMax).\r
2799 //\r
2800 SourceLen = StrnLenS (Source, DestMax);\r
2801 if (Length >= DestMax) {\r
2802 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2803 }\r
2804\r
2805 //\r
2806 // 5. Copying shall not take place between objects that overlap.\r
2807 //\r
2808 if (SourceLen > Length) {\r
2809 SourceLen = Length;\r
2810 }\r
2f88bd3a
MK
2811\r
2812 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof (CHAR16)), RETURN_ACCESS_DENIED);\r
02263214
HW
2813\r
2814 *DestinationLength = 0;\r
2815\r
2816 //\r
2817 // Convert string\r
2818 //\r
2819 while ((*Source != 0) && (SourceLen > 0)) {\r
2820 //\r
2821 // If any Unicode characters in Source contain non-zero value in the upper\r
2822 // 8 bits, then ASSERT().\r
2823 //\r
2824 ASSERT (*Source < 0x100);\r
2f88bd3a 2825 *(Destination++) = (CHAR8)*(Source++);\r
02263214
HW
2826 SourceLen--;\r
2827 (*DestinationLength)++;\r
2828 }\r
2f88bd3a 2829\r
02263214
HW
2830 *Destination = 0;\r
2831\r
2832 return RETURN_SUCCESS;\r
2833}\r
3ab41b7a
JY
2834\r
2835/**\r
2836 Convert one Null-terminated ASCII string to a Null-terminated\r
2837 Unicode string.\r
2838\r
2839 This function is similar to StrCpyS.\r
2840\r
2841 This function converts the contents of the ASCII string Source to the Unicode\r
2842 string Destination. The function terminates the Unicode string Destination by\r
2843 appending a Null-terminator character at the end.\r
2844\r
2845 The caller is responsible to make sure Destination points to a buffer with size\r
2846 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.\r
2847\r
2848 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
3ab41b7a
JY
2849\r
2850 If an error is returned, then the Destination is unmodified.\r
2851\r
2852 @param Source The pointer to a Null-terminated ASCII string.\r
2853 @param Destination The pointer to a Null-terminated Unicode string.\r
2854 @param DestMax The maximum number of Destination Unicode\r
2855 char, including terminating null char.\r
2856\r
2857 @retval RETURN_SUCCESS String is converted.\r
2858 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
2859 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2860 If Source is NULL.\r
2861 If PcdMaximumUnicodeStringLength is not zero,\r
2862 and DestMax is greater than\r
2863 PcdMaximumUnicodeStringLength.\r
2864 If PcdMaximumAsciiStringLength is not zero,\r
2865 and DestMax is greater than\r
2866 PcdMaximumAsciiStringLength.\r
2867 If DestMax is 0.\r
2868 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2869\r
2870**/\r
2871RETURN_STATUS\r
2872EFIAPI\r
2873AsciiStrToUnicodeStrS (\r
2f88bd3a
MK
2874 IN CONST CHAR8 *Source,\r
2875 OUT CHAR16 *Destination,\r
2876 IN UINTN DestMax\r
3ab41b7a
JY
2877 )\r
2878{\r
2f88bd3a 2879 UINTN SourceLen;\r
3ab41b7a 2880\r
2f88bd3a 2881 ASSERT (((UINTN)Destination & BIT0) == 0);\r
3ab41b7a
JY
2882\r
2883 //\r
2884 // 1. Neither Destination nor Source shall be a null pointer.\r
2885 //\r
2886 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2887 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2888\r
2889 //\r
2890 // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.\r
2891 //\r
2892 if (RSIZE_MAX != 0) {\r
2893 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2894 }\r
2f88bd3a 2895\r
3ab41b7a
JY
2896 if (ASCII_RSIZE_MAX != 0) {\r
2897 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2898 }\r
2899\r
2900 //\r
2901 // 3. DestMax shall not equal zero.\r
2902 //\r
2903 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2904\r
2905 //\r
2906 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
2907 //\r
2908 SourceLen = AsciiStrnLenS (Source, DestMax);\r
2909 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2910\r
2911 //\r
2912 // 5. Copying shall not take place between objects that overlap.\r
2913 //\r
2f88bd3a 2914 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof (CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
3ab41b7a
JY
2915\r
2916 //\r
2917 // Convert string\r
2918 //\r
2919 while (*Source != '\0') {\r
0dab5770 2920 *(Destination++) = (CHAR16)(UINT8)*(Source++);\r
3ab41b7a 2921 }\r
2f88bd3a 2922\r
3ab41b7a
JY
2923 *Destination = '\0';\r
2924\r
2925 return RETURN_SUCCESS;\r
2926}\r
02263214
HW
2927\r
2928/**\r
2929 Convert not more than Length successive characters from a Null-terminated\r
2930 Ascii string to a Null-terminated Unicode string. If no null char is copied\r
2931 from Source, then Destination[Length] is always set to null.\r
2932\r
2933 This function converts not more than Length successive characters from the\r
2934 Ascii string Source to the Unicode string Destination. The function\r
2935 terminates the Unicode string Destination by appending a Null-terminator\r
2936 character at the end.\r
2937\r
2938 The caller is responsible to make sure Destination points to a buffer with\r
2939 size not smaller than\r
2940 ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes.\r
2941\r
2942 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
02263214
HW
2943\r
2944 If an error is returned, then Destination and DestinationLength are\r
2945 unmodified.\r
2946\r
2947 @param Source The pointer to a Null-terminated Ascii string.\r
2948 @param Length The maximum number of Ascii characters to convert.\r
2949 @param Destination The pointer to a Null-terminated Unicode string.\r
2950 @param DestMax The maximum number of Destination Unicode char,\r
2951 including terminating null char.\r
2952 @param DestinationLength The number of Ascii characters converted.\r
2953\r
2954 @retval RETURN_SUCCESS String is converted.\r
2955 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2956 If Source is NULL.\r
2957 If DestinationLength is NULL.\r
2958 If PcdMaximumUnicodeStringLength is not\r
2959 zero, and Length or DestMax is greater than\r
2960 PcdMaximumUnicodeStringLength.\r
2961 If PcdMaximumAsciiStringLength is not zero,\r
2962 and Length or DestMax is greater than\r
2963 PcdMaximumAsciiStringLength.\r
2964 If DestMax is 0.\r
2965 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than\r
2966 MIN(AsciiStrLen(Source), Length).\r
2967 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2968\r
2969**/\r
2970RETURN_STATUS\r
2971EFIAPI\r
2972AsciiStrnToUnicodeStrS (\r
2f88bd3a
MK
2973 IN CONST CHAR8 *Source,\r
2974 IN UINTN Length,\r
2975 OUT CHAR16 *Destination,\r
2976 IN UINTN DestMax,\r
2977 OUT UINTN *DestinationLength\r
02263214
HW
2978 )\r
2979{\r
2f88bd3a 2980 UINTN SourceLen;\r
02263214 2981\r
2f88bd3a 2982 ASSERT (((UINTN)Destination & BIT0) == 0);\r
02263214
HW
2983\r
2984 //\r
2985 // 1. None of Destination, Source or DestinationLength shall be a null\r
2986 // pointer.\r
2987 //\r
2988 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2989 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2990 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);\r
2991\r
2992 //\r
2993 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or\r
2994 // RSIZE_MAX.\r
2995 //\r
2996 if (RSIZE_MAX != 0) {\r
2997 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2998 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2999 }\r
2f88bd3a 3000\r
02263214
HW
3001 if (ASCII_RSIZE_MAX != 0) {\r
3002 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
3003 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
3004 }\r
3005\r
3006 //\r
3007 // 3. DestMax shall not equal zero.\r
3008 //\r
3009 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
3010\r
3011 //\r
3012 // 4. If Length is not less than DestMax, then DestMax shall be greater than\r
3013 // AsciiStrnLenS(Source, DestMax).\r
3014 //\r
3015 SourceLen = AsciiStrnLenS (Source, DestMax);\r
3016 if (Length >= DestMax) {\r
3017 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
3018 }\r
3019\r
3020 //\r
3021 // 5. Copying shall not take place between objects that overlap.\r
3022 //\r
3023 if (SourceLen > Length) {\r
3024 SourceLen = Length;\r
3025 }\r
2f88bd3a
MK
3026\r
3027 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof (CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
02263214
HW
3028\r
3029 *DestinationLength = 0;\r
3030\r
3031 //\r
3032 // Convert string\r
3033 //\r
3034 while ((*Source != 0) && (SourceLen > 0)) {\r
0dab5770 3035 *(Destination++) = (CHAR16)(UINT8)*(Source++);\r
02263214
HW
3036 SourceLen--;\r
3037 (*DestinationLength)++;\r
3038 }\r
2f88bd3a 3039\r
02263214
HW
3040 *Destination = 0;\r
3041\r
3042 return RETURN_SUCCESS;\r
3043}\r
fb4dd857
RN
3044\r
3045/**\r
3046 Convert a Null-terminated ASCII string to IPv6 address and prefix length.\r
3047\r
3048 This function outputs a value of type IPv6_ADDRESS and may output a value\r
3049 of type UINT8 by interpreting the contents of the ASCII string specified\r
3050 by String. The format of the input ASCII string String is as follows:\r
3051\r
3052 X:X:X:X:X:X:X:X[/P]\r
3053\r
3054 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and\r
3055 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low\r
3056 memory address and high byte is stored in high memory address. P contains decimal\r
3057 digit characters in the range [0-9]. The running zero in the beginning of P will\r
3058 be ignored. /P is optional.\r
3059\r
3060 When /P is not in the String, the function stops at the first character that is\r
3061 not a valid hexadecimal digit character after eight X's are converted.\r
3062\r
3063 When /P is in the String, the function stops at the first character that is not\r
3064 a valid decimal digit character after P is converted.\r
3065\r
3066 "::" can be used to compress one or more groups of X when X contains only 0.\r
3067 The "::" can only appear once in the String.\r
3068\r
fb4dd857
RN
3069 If EndPointer is not NULL and Address is translated from String, a pointer\r
3070 to the character that stopped the scan is stored at the location pointed to\r
3071 by EndPointer.\r
3072\r
3073 @param String Pointer to a Null-terminated ASCII string.\r
3074 @param EndPointer Pointer to character that stops scan.\r
3075 @param Address Pointer to the converted IPv6 address.\r
3076 @param PrefixLength Pointer to the converted IPv6 address prefix\r
3077 length. MAX_UINT8 is returned when /P is\r
3078 not in the String.\r
3079\r
3080 @retval RETURN_SUCCESS Address is translated from String.\r
3081 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
3082 If Data is NULL.\r
3083 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal\r
3084 digit characters.\r
3085 If String contains "::" and number of X\r
3086 is not less than 8.\r
3087 If P starts with character that is not a\r
3088 valid decimal digit character.\r
3089 If the decimal number converted from P\r
3090 exceeds 128.\r
3091\r
3092**/\r
3093RETURN_STATUS\r
3094EFIAPI\r
3095AsciiStrToIpv6Address (\r
2f88bd3a
MK
3096 IN CONST CHAR8 *String,\r
3097 OUT CHAR8 **EndPointer OPTIONAL,\r
3098 OUT IPv6_ADDRESS *Address,\r
3099 OUT UINT8 *PrefixLength OPTIONAL\r
fb4dd857
RN
3100 )\r
3101{\r
2f88bd3a
MK
3102 RETURN_STATUS Status;\r
3103 UINTN AddressIndex;\r
3104 UINTN Uintn;\r
3105 IPv6_ADDRESS LocalAddress;\r
3106 UINT8 LocalPrefixLength;\r
3107 CONST CHAR8 *Pointer;\r
3108 CHAR8 *End;\r
3109 UINTN CompressStart;\r
3110 BOOLEAN ExpectPrefix;\r
fb4dd857
RN
3111\r
3112 LocalPrefixLength = MAX_UINT8;\r
3113 CompressStart = ARRAY_SIZE (Address->Addr);\r
3114 ExpectPrefix = FALSE;\r
3115\r
3116 //\r
3117 // None of String or Address shall be a null pointer.\r
3118 //\r
3119 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
3120 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);\r
3121\r
3122 for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {\r
3123 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer)) {\r
3124 if (*Pointer != ':') {\r
3125 //\r
3126 // ":" or "/" should be followed by digit characters.\r
3127 //\r
3128 return RETURN_UNSUPPORTED;\r
3129 }\r
3130\r
3131 //\r
3132 // Meet second ":" after previous ":" or "/"\r
3133 // or meet first ":" in the beginning of String.\r
3134 //\r
3135 if (ExpectPrefix) {\r
3136 //\r
3137 // ":" shall not be after "/"\r
3138 //\r
3139 return RETURN_UNSUPPORTED;\r
3140 }\r
3141\r
2f88bd3a 3142 if ((CompressStart != ARRAY_SIZE (Address->Addr)) || (AddressIndex == ARRAY_SIZE (Address->Addr))) {\r
fb4dd857
RN
3143 //\r
3144 // "::" can only appear once.\r
3145 // "::" can only appear when address is not full length.\r
3146 //\r
3147 return RETURN_UNSUPPORTED;\r
3148 } else {\r
3149 //\r
3150 // Remember the start of zero compressing.\r
3151 //\r
3152 CompressStart = AddressIndex;\r
3153 Pointer++;\r
3154\r
3155 if (CompressStart == 0) {\r
3156 if (*Pointer != ':') {\r
3157 //\r
3158 // Single ":" shall not be in the beginning of String.\r
3159 //\r
3160 return RETURN_UNSUPPORTED;\r
3161 }\r
2f88bd3a 3162\r
fb4dd857
RN
3163 Pointer++;\r
3164 }\r
3165 }\r
3166 }\r
3167\r
3168 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer)) {\r
3169 if (*Pointer == '/') {\r
3170 //\r
3171 // Might be optional "/P" after "::".\r
3172 //\r
3173 if (CompressStart != AddressIndex) {\r
3174 return RETURN_UNSUPPORTED;\r
3175 }\r
3176 } else {\r
3177 break;\r
3178 }\r
3179 } else {\r
3180 if (!ExpectPrefix) {\r
3181 //\r
3182 // Get X.\r
3183 //\r
3184 Status = AsciiStrHexToUintnS (Pointer, &End, &Uintn);\r
2f88bd3a 3185 if (RETURN_ERROR (Status) || (End - Pointer > 4)) {\r
fb4dd857
RN
3186 //\r
3187 // Number of hexadecimal digit characters is no more than 4.\r
3188 //\r
3189 return RETURN_UNSUPPORTED;\r
3190 }\r
2f88bd3a 3191\r
fb4dd857
RN
3192 Pointer = End;\r
3193 //\r
3194 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.\r
3195 //\r
5b0ce08a 3196 ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));\r
2f88bd3a
MK
3197 LocalAddress.Addr[AddressIndex] = (UINT8)((UINT16)Uintn >> 8);\r
3198 LocalAddress.Addr[AddressIndex + 1] = (UINT8)Uintn;\r
3199 AddressIndex += 2;\r
fb4dd857
RN
3200 } else {\r
3201 //\r
3202 // Get P, then exit the loop.\r
3203 //\r
3204 Status = AsciiStrDecimalToUintnS (Pointer, &End, &Uintn);\r
2f88bd3a 3205 if (RETURN_ERROR (Status) || (End == Pointer) || (Uintn > 128)) {\r
fb4dd857
RN
3206 //\r
3207 // Prefix length should not exceed 128.\r
3208 //\r
3209 return RETURN_UNSUPPORTED;\r
3210 }\r
2f88bd3a
MK
3211\r
3212 LocalPrefixLength = (UINT8)Uintn;\r
3213 Pointer = End;\r
fb4dd857
RN
3214 break;\r
3215 }\r
3216 }\r
3217\r
3218 //\r
3219 // Skip ':' or "/"\r
3220 //\r
3221 if (*Pointer == '/') {\r
3222 ExpectPrefix = TRUE;\r
3223 } else if (*Pointer == ':') {\r
3224 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
3225 //\r
3226 // Meet additional ":" after all 8 16-bit address\r
3227 //\r
3228 break;\r
3229 }\r
3230 } else {\r
3231 //\r
3232 // Meet other character that is not "/" or ":" after all 8 16-bit address\r
3233 //\r
3234 break;\r
3235 }\r
2f88bd3a 3236\r
fb4dd857
RN
3237 Pointer++;\r
3238 }\r
3239\r
2f88bd3a
MK
3240 if (((AddressIndex == ARRAY_SIZE (Address->Addr)) && (CompressStart != ARRAY_SIZE (Address->Addr))) ||\r
3241 ((AddressIndex != ARRAY_SIZE (Address->Addr)) && (CompressStart == ARRAY_SIZE (Address->Addr)))\r
3242 )\r
3243 {\r
fb4dd857
RN
3244 //\r
3245 // Full length of address shall not have compressing zeros.\r
3246 // Non-full length of address shall have compressing zeros.\r
3247 //\r
3248 return RETURN_UNSUPPORTED;\r
3249 }\r
2f88bd3a 3250\r
fb4dd857
RN
3251 CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);\r
3252 ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);\r
5b0ce08a
RN
3253 if (AddressIndex > CompressStart) {\r
3254 CopyMem (\r
3255 &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],\r
3256 &LocalAddress.Addr[CompressStart],\r
3257 AddressIndex - CompressStart\r
973f8862 3258 );\r
5b0ce08a 3259 }\r
fb4dd857
RN
3260\r
3261 if (PrefixLength != NULL) {\r
3262 *PrefixLength = LocalPrefixLength;\r
3263 }\r
2f88bd3a 3264\r
fb4dd857 3265 if (EndPointer != NULL) {\r
2f88bd3a 3266 *EndPointer = (CHAR8 *)Pointer;\r
fb4dd857
RN
3267 }\r
3268\r
3269 return RETURN_SUCCESS;\r
3270}\r
3271\r
3272/**\r
3273 Convert a Null-terminated ASCII string to IPv4 address and prefix length.\r
3274\r
3275 This function outputs a value of type IPv4_ADDRESS and may output a value\r
3276 of type UINT8 by interpreting the contents of the ASCII string specified\r
3277 by String. The format of the input ASCII string String is as follows:\r
3278\r
3279 D.D.D.D[/P]\r
3280\r
3281 D and P are decimal digit characters in the range [0-9]. The running zero in\r
3282 the beginning of D and P will be ignored. /P is optional.\r
3283\r
3284 When /P is not in the String, the function stops at the first character that is\r
3285 not a valid decimal digit character after four D's are converted.\r
3286\r
3287 When /P is in the String, the function stops at the first character that is not\r
3288 a valid decimal digit character after P is converted.\r
3289\r
fb4dd857
RN
3290 If EndPointer is not NULL and Address is translated from String, a pointer\r
3291 to the character that stopped the scan is stored at the location pointed to\r
3292 by EndPointer.\r
3293\r
3294 @param String Pointer to a Null-terminated ASCII string.\r
3295 @param EndPointer Pointer to character that stops scan.\r
3296 @param Address Pointer to the converted IPv4 address.\r
3297 @param PrefixLength Pointer to the converted IPv4 address prefix\r
3298 length. MAX_UINT8 is returned when /P is\r
3299 not in the String.\r
3300\r
3301 @retval RETURN_SUCCESS Address is translated from String.\r
3302 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
3303 If Data is NULL.\r
3304 @retval RETURN_UNSUPPORTED If String is not in the correct format.\r
3305 If any decimal number converted from D\r
3306 exceeds 255.\r
3307 If the decimal number converted from P\r
3308 exceeds 32.\r
3309\r
3310**/\r
3311RETURN_STATUS\r
3312EFIAPI\r
3313AsciiStrToIpv4Address (\r
2f88bd3a
MK
3314 IN CONST CHAR8 *String,\r
3315 OUT CHAR8 **EndPointer OPTIONAL,\r
3316 OUT IPv4_ADDRESS *Address,\r
3317 OUT UINT8 *PrefixLength OPTIONAL\r
fb4dd857
RN
3318 )\r
3319{\r
2f88bd3a
MK
3320 RETURN_STATUS Status;\r
3321 UINTN AddressIndex;\r
3322 UINTN Uintn;\r
3323 IPv4_ADDRESS LocalAddress;\r
3324 UINT8 LocalPrefixLength;\r
3325 CHAR8 *Pointer;\r
fb4dd857
RN
3326\r
3327 LocalPrefixLength = MAX_UINT8;\r
3328\r
3329 //\r
3330 // None of String or Address shall be a null pointer.\r
3331 //\r
3332 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
3333 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);\r
3334\r
2f88bd3a 3335 for (Pointer = (CHAR8 *)String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {\r
fb4dd857
RN
3336 if (!InternalAsciiIsDecimalDigitCharacter (*Pointer)) {\r
3337 //\r
3338 // D or P contains invalid characters.\r
3339 //\r
3340 break;\r
3341 }\r
3342\r
3343 //\r
3344 // Get D or P.\r
3345 //\r
2f88bd3a 3346 Status = AsciiStrDecimalToUintnS ((CONST CHAR8 *)Pointer, &Pointer, &Uintn);\r
fb4dd857
RN
3347 if (RETURN_ERROR (Status)) {\r
3348 return RETURN_UNSUPPORTED;\r
3349 }\r
2f88bd3a 3350\r
fb4dd857
RN
3351 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
3352 //\r
3353 // It's P.\r
3354 //\r
3355 if (Uintn > 32) {\r
3356 return RETURN_UNSUPPORTED;\r
3357 }\r
2f88bd3a
MK
3358\r
3359 LocalPrefixLength = (UINT8)Uintn;\r
fb4dd857
RN
3360 } else {\r
3361 //\r
3362 // It's D.\r
3363 //\r
3364 if (Uintn > MAX_UINT8) {\r
3365 return RETURN_UNSUPPORTED;\r
3366 }\r
2f88bd3a
MK
3367\r
3368 LocalAddress.Addr[AddressIndex] = (UINT8)Uintn;\r
fb4dd857
RN
3369 AddressIndex++;\r
3370 }\r
3371\r
3372 //\r
3373 // Check the '.' or '/', depending on the AddressIndex.\r
3374 //\r
3375 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
3376 if (*Pointer == '/') {\r
3377 //\r
3378 // '/P' is in the String.\r
3379 // Skip "/" and get P in next loop.\r
3380 //\r
3381 Pointer++;\r
3382 } else {\r
3383 //\r
3384 // '/P' is not in the String.\r
3385 //\r
3386 break;\r
3387 }\r
3388 } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {\r
3389 if (*Pointer == '.') {\r
3390 //\r
3391 // D should be followed by '.'\r
3392 //\r
3393 Pointer++;\r
3394 } else {\r
3395 return RETURN_UNSUPPORTED;\r
3396 }\r
3397 }\r
3398 }\r
3399\r
3400 if (AddressIndex < ARRAY_SIZE (Address->Addr)) {\r
3401 return RETURN_UNSUPPORTED;\r
3402 }\r
3403\r
3404 CopyMem (Address, &LocalAddress, sizeof (*Address));\r
3405 if (PrefixLength != NULL) {\r
3406 *PrefixLength = LocalPrefixLength;\r
3407 }\r
2f88bd3a 3408\r
fb4dd857
RN
3409 if (EndPointer != NULL) {\r
3410 *EndPointer = Pointer;\r
3411 }\r
3412\r
3413 return RETURN_SUCCESS;\r
3414}\r
3415\r
3416/**\r
3417 Convert a Null-terminated ASCII GUID string to a value of type\r
3418 EFI_GUID.\r
3419\r
3420 This function outputs a GUID value by interpreting the contents of\r
3421 the ASCII string specified by String. The format of the input\r
3422 ASCII string String consists of 36 characters, as follows:\r
3423\r
3424 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp\r
3425\r
3426 The pairs aa - pp are two characters in the range [0-9], [a-f] and\r
3427 [A-F], with each pair representing a single byte hexadecimal value.\r
3428\r
3429 The mapping between String and the EFI_GUID structure is as follows:\r
3430 aa Data1[24:31]\r
3431 bb Data1[16:23]\r
3432 cc Data1[8:15]\r
3433 dd Data1[0:7]\r
3434 ee Data2[8:15]\r
3435 ff Data2[0:7]\r
3436 gg Data3[8:15]\r
3437 hh Data3[0:7]\r
3438 ii Data4[0:7]\r
3439 jj Data4[8:15]\r
3440 kk Data4[16:23]\r
3441 ll Data4[24:31]\r
3442 mm Data4[32:39]\r
3443 nn Data4[40:47]\r
3444 oo Data4[48:55]\r
3445 pp Data4[56:63]\r
3446\r
fb4dd857
RN
3447 @param String Pointer to a Null-terminated ASCII string.\r
3448 @param Guid Pointer to the converted GUID.\r
3449\r
3450 @retval RETURN_SUCCESS Guid is translated from String.\r
3451 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
3452 If Data is NULL.\r
3453 @retval RETURN_UNSUPPORTED If String is not as the above format.\r
3454\r
3455**/\r
3456RETURN_STATUS\r
3457EFIAPI\r
3458AsciiStrToGuid (\r
2f88bd3a
MK
3459 IN CONST CHAR8 *String,\r
3460 OUT GUID *Guid\r
fb4dd857
RN
3461 )\r
3462{\r
2f88bd3a
MK
3463 RETURN_STATUS Status;\r
3464 GUID LocalGuid;\r
fb4dd857
RN
3465\r
3466 //\r
3467 // None of String or Guid shall be a null pointer.\r
3468 //\r
3469 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
3470 SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);\r
3471\r
3472 //\r
3473 // Get aabbccdd in big-endian.\r
3474 //\r
2f88bd3a
MK
3475 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *)&LocalGuid.Data1, sizeof (LocalGuid.Data1));\r
3476 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data1)] != '-')) {\r
fb4dd857
RN
3477 return RETURN_UNSUPPORTED;\r
3478 }\r
2f88bd3a 3479\r
fb4dd857
RN
3480 //\r
3481 // Convert big-endian to little-endian.\r
3482 //\r
3483 LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);\r
2f88bd3a 3484 String += 2 * sizeof (LocalGuid.Data1) + 1;\r
fb4dd857
RN
3485\r
3486 //\r
3487 // Get eeff in big-endian.\r
3488 //\r
2f88bd3a
MK
3489 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *)&LocalGuid.Data2, sizeof (LocalGuid.Data2));\r
3490 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data2)] != '-')) {\r
fb4dd857
RN
3491 return RETURN_UNSUPPORTED;\r
3492 }\r
2f88bd3a 3493\r
fb4dd857
RN
3494 //\r
3495 // Convert big-endian to little-endian.\r
3496 //\r
3497 LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);\r
2f88bd3a 3498 String += 2 * sizeof (LocalGuid.Data2) + 1;\r
fb4dd857
RN
3499\r
3500 //\r
3501 // Get gghh in big-endian.\r
3502 //\r
2f88bd3a
MK
3503 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *)&LocalGuid.Data3, sizeof (LocalGuid.Data3));\r
3504 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data3)] != '-')) {\r
fb4dd857
RN
3505 return RETURN_UNSUPPORTED;\r
3506 }\r
2f88bd3a 3507\r
fb4dd857
RN
3508 //\r
3509 // Convert big-endian to little-endian.\r
3510 //\r
3511 LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);\r
2f88bd3a 3512 String += 2 * sizeof (LocalGuid.Data3) + 1;\r
fb4dd857
RN
3513\r
3514 //\r
3515 // Get iijj.\r
3516 //\r
3517 Status = AsciiStrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);\r
2f88bd3a 3518 if (RETURN_ERROR (Status) || (String[2 * 2] != '-')) {\r
fb4dd857
RN
3519 return RETURN_UNSUPPORTED;\r
3520 }\r
2f88bd3a 3521\r
fb4dd857
RN
3522 String += 2 * 2 + 1;\r
3523\r
3524 //\r
3525 // Get kkllmmnnoopp.\r
3526 //\r
3527 Status = AsciiStrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);\r
3528 if (RETURN_ERROR (Status)) {\r
3529 return RETURN_UNSUPPORTED;\r
3530 }\r
3531\r
3532 CopyGuid (Guid, &LocalGuid);\r
3533 return RETURN_SUCCESS;\r
3534}\r
3535\r
3536/**\r
3537 Convert a Null-terminated ASCII hexadecimal string to a byte array.\r
3538\r
3539 This function outputs a byte array by interpreting the contents of\r
3540 the ASCII string specified by String in hexadecimal format. The format of\r
3541 the input ASCII string String is:\r
3542\r
3543 [XX]*\r
3544\r
3545 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].\r
3546 The function decodes every two hexadecimal digit characters as one byte. The\r
3547 decoding stops after Length of characters and outputs Buffer containing\r
3548 (Length / 2) bytes.\r
3549\r
fb4dd857
RN
3550 @param String Pointer to a Null-terminated ASCII string.\r
3551 @param Length The number of ASCII characters to decode.\r
3552 @param Buffer Pointer to the converted bytes array.\r
3553 @param MaxBufferSize The maximum size of Buffer.\r
3554\r
3555 @retval RETURN_SUCCESS Buffer is translated from String.\r
3556 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
3557 If Data is NULL.\r
3558 If Length is not multiple of 2.\r
3559 If PcdMaximumAsciiStringLength is not zero,\r
3560 and Length is greater than\r
3561 PcdMaximumAsciiStringLength.\r
3562 @retval RETURN_UNSUPPORTED If Length of characters from String contain\r
3563 a character that is not valid hexadecimal\r
3564 digit characters, or a Null-terminator.\r
3565 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).\r
3566**/\r
3567RETURN_STATUS\r
3568EFIAPI\r
3569AsciiStrHexToBytes (\r
2f88bd3a
MK
3570 IN CONST CHAR8 *String,\r
3571 IN UINTN Length,\r
3572 OUT UINT8 *Buffer,\r
3573 IN UINTN MaxBufferSize\r
fb4dd857
RN
3574 )\r
3575{\r
2f88bd3a 3576 UINTN Index;\r
fb4dd857
RN
3577\r
3578 //\r
3579 // 1. None of String or Buffer shall be a null pointer.\r
3580 //\r
3581 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
3582 SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);\r
3583\r
3584 //\r
3585 // 2. Length shall not be greater than ASCII_RSIZE_MAX.\r
3586 //\r
3587 if (ASCII_RSIZE_MAX != 0) {\r
3588 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
3589 }\r
3590\r
3591 //\r
3592 // 3. Length shall not be odd.\r
3593 //\r
3594 SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);\r
3595\r
3596 //\r
3597 // 4. MaxBufferSize shall equal to or greater than Length / 2.\r
3598 //\r
3599 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);\r
3600\r
3601 //\r
3602 // 5. String shall not contains invalid hexadecimal digits.\r
3603 //\r
3604 for (Index = 0; Index < Length; Index++) {\r
3605 if (!InternalAsciiIsHexaDecimalDigitCharacter (String[Index])) {\r
3606 break;\r
3607 }\r
3608 }\r
2f88bd3a 3609\r
fb4dd857
RN
3610 if (Index != Length) {\r
3611 return RETURN_UNSUPPORTED;\r
3612 }\r
3613\r
3614 //\r
3615 // Convert the hex string to bytes.\r
3616 //\r
2f88bd3a 3617 for (Index = 0; Index < Length; Index++) {\r
fb4dd857
RN
3618 //\r
3619 // For even characters, write the upper nibble for each buffer byte,\r
3620 // and for even characters, the lower nibble.\r
3621 //\r
3622 if ((Index & BIT0) == 0) {\r
2f88bd3a 3623 Buffer[Index / 2] = (UINT8)InternalAsciiHexCharToUintn (String[Index]) << 4;\r
fb4dd857 3624 } else {\r
2f88bd3a 3625 Buffer[Index / 2] |= (UINT8)InternalAsciiHexCharToUintn (String[Index]);\r
fb4dd857
RN
3626 }\r
3627 }\r
2f88bd3a 3628\r
fb4dd857
RN
3629 return RETURN_SUCCESS;\r
3630}\r