1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191 |
- /** @file
- Common basic Library Functions
- Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <ctype.h>
- #ifdef __GNUC__
- #include <unistd.h>
- #else
- #include <direct.h>
- #endif
- #include "CommonLib.h"
- #include "EfiUtilityMsgs.h"
- #define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \
- do { \
- ASSERT (Expression); \
- if (!(Expression)) { \
- return Status; \
- } \
- } while (FALSE)
- VOID
- PeiZeroMem (
- IN VOID *Buffer,
- IN UINTN Size
- )
- /*++
- Routine Description:
- Set Buffer to zero for Size bytes.
- Arguments:
- Buffer - Memory to set.
- Size - Number of bytes to set
- Returns:
- None
- --*/
- {
- INT8 *Ptr;
- Ptr = Buffer;
- while (Size--) {
- *(Ptr++) = 0;
- }
- }
- VOID
- PeiCopyMem (
- IN VOID *Destination,
- IN VOID *Source,
- IN UINTN Length
- )
- /*++
- Routine Description:
- Copy Length bytes from Source to Destination.
- Arguments:
- Destination - Target of copy
- Source - Place to copy from
- Length - Number of bytes to copy
- Returns:
- None
- --*/
- {
- CHAR8 *Destination8;
- CHAR8 *Source8;
- Destination8 = Destination;
- Source8 = Source;
- while (Length--) {
- *(Destination8++) = *(Source8++);
- }
- }
- VOID
- ZeroMem (
- IN VOID *Buffer,
- IN UINTN Size
- )
- {
- PeiZeroMem (Buffer, Size);
- }
- VOID
- CopyMem (
- IN VOID *Destination,
- IN VOID *Source,
- IN UINTN Length
- )
- {
- PeiCopyMem (Destination, Source, Length);
- }
- INTN
- CompareGuid (
- IN EFI_GUID *Guid1,
- IN EFI_GUID *Guid2
- )
- /*++
- Routine Description:
- Compares to GUIDs
- Arguments:
- Guid1 - guid to compare
- Guid2 - guid to compare
- Returns:
- = 0 if Guid1 == Guid2
- != 0 if Guid1 != Guid2
- --*/
- {
- INT32 *g1;
- INT32 *g2;
- INT32 r;
- //
- // Compare 32 bits at a time
- //
- g1 = (INT32 *) Guid1;
- g2 = (INT32 *) Guid2;
- r = g1[0] - g2[0];
- r |= g1[1] - g2[1];
- r |= g1[2] - g2[2];
- r |= g1[3] - g2[3];
- return r;
- }
- EFI_STATUS
- GetFileImage (
- IN CHAR8 *InputFileName,
- OUT CHAR8 **InputFileImage,
- OUT UINT32 *BytesRead
- )
- /*++
- Routine Description:
- This function opens a file and reads it into a memory buffer. The function
- will allocate the memory buffer and returns the size of the buffer.
- Arguments:
- InputFileName The name of the file to read.
- InputFileImage A pointer to the memory buffer.
- BytesRead The size of the memory buffer.
- Returns:
- EFI_SUCCESS The function completed successfully.
- EFI_INVALID_PARAMETER One of the input parameters was invalid.
- EFI_ABORTED An error occurred.
- EFI_OUT_OF_RESOURCES No resource to complete operations.
- --*/
- {
- FILE *InputFile;
- UINT32 FileSize;
- //
- // Verify input parameters.
- //
- if (InputFileName == NULL || strlen (InputFileName) == 0 || InputFileImage == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // Open the file and copy contents into a memory buffer.
- //
- //
- // Open the file
- //
- InputFile = fopen (LongFilePath (InputFileName), "rb");
- if (InputFile == NULL) {
- Error (NULL, 0, 0001, "Error opening the input file", InputFileName);
- return EFI_ABORTED;
- }
- //
- // Go to the end so that we can determine the file size
- //
- if (fseek (InputFile, 0, SEEK_END)) {
- Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
- fclose (InputFile);
- return EFI_ABORTED;
- }
- //
- // Get the file size
- //
- FileSize = ftell (InputFile);
- if (FileSize == -1) {
- Error (NULL, 0, 0003, "Error parsing the input file", InputFileName);
- fclose (InputFile);
- return EFI_ABORTED;
- }
- //
- // Allocate a buffer
- //
- *InputFileImage = malloc (FileSize);
- if (*InputFileImage == NULL) {
- fclose (InputFile);
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Reset to the beginning of the file
- //
- if (fseek (InputFile, 0, SEEK_SET)) {
- Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
- fclose (InputFile);
- free (*InputFileImage);
- *InputFileImage = NULL;
- return EFI_ABORTED;
- }
- //
- // Read all of the file contents.
- //
- *BytesRead = fread (*InputFileImage, sizeof (UINT8), FileSize, InputFile);
- if (*BytesRead != sizeof (UINT8) * FileSize) {
- Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
- fclose (InputFile);
- free (*InputFileImage);
- *InputFileImage = NULL;
- return EFI_ABORTED;
- }
- //
- // Close the file
- //
- fclose (InputFile);
- return EFI_SUCCESS;
- }
- EFI_STATUS
- PutFileImage (
- IN CHAR8 *OutputFileName,
- IN CHAR8 *OutputFileImage,
- IN UINT32 BytesToWrite
- )
- /*++
- Routine Description:
- This function opens a file and writes OutputFileImage into the file.
- Arguments:
- OutputFileName The name of the file to write.
- OutputFileImage A pointer to the memory buffer.
- BytesToWrite The size of the memory buffer.
- Returns:
- EFI_SUCCESS The function completed successfully.
- EFI_INVALID_PARAMETER One of the input parameters was invalid.
- EFI_ABORTED An error occurred.
- EFI_OUT_OF_RESOURCES No resource to complete operations.
- --*/
- {
- FILE *OutputFile;
- UINT32 BytesWrote;
- //
- // Verify input parameters.
- //
- if (OutputFileName == NULL || strlen (OutputFileName) == 0 || OutputFileImage == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // Open the file and copy contents into a memory buffer.
- //
- //
- // Open the file
- //
- OutputFile = fopen (LongFilePath (OutputFileName), "wb");
- if (OutputFile == NULL) {
- Error (NULL, 0, 0001, "Error opening the output file", OutputFileName);
- return EFI_ABORTED;
- }
- //
- // Write all of the file contents.
- //
- BytesWrote = fwrite (OutputFileImage, sizeof (UINT8), BytesToWrite, OutputFile);
- if (BytesWrote != sizeof (UINT8) * BytesToWrite) {
- Error (NULL, 0, 0002, "Error writing the output file", OutputFileName);
- fclose (OutputFile);
- return EFI_ABORTED;
- }
- //
- // Close the file
- //
- fclose (OutputFile);
- return EFI_SUCCESS;
- }
- UINT8
- CalculateChecksum8 (
- IN UINT8 *Buffer,
- IN UINTN Size
- )
- /*++
- Routine Description:
- This function calculates the value needed for a valid UINT8 checksum
- Arguments:
- Buffer Pointer to buffer containing byte data of component.
- Size Size of the buffer
- Returns:
- The 8 bit checksum value needed.
- --*/
- {
- return (UINT8) (0x100 - CalculateSum8 (Buffer, Size));
- }
- UINT8
- CalculateSum8 (
- IN UINT8 *Buffer,
- IN UINTN Size
- )
- /*++
- Routine Description::
- This function calculates the UINT8 sum for the requested region.
- Arguments:
- Buffer Pointer to buffer containing byte data of component.
- Size Size of the buffer
- Returns:
- The 8 bit checksum value needed.
- --*/
- {
- UINTN Index;
- UINT8 Sum;
- Sum = 0;
- //
- // Perform the byte sum for buffer
- //
- for (Index = 0; Index < Size; Index++) {
- Sum = (UINT8) (Sum + Buffer[Index]);
- }
- return Sum;
- }
- UINT16
- CalculateChecksum16 (
- IN UINT16 *Buffer,
- IN UINTN Size
- )
- /*++
- Routine Description::
- This function calculates the value needed for a valid UINT16 checksum
- Arguments:
- Buffer Pointer to buffer containing byte data of component.
- Size Size of the buffer
- Returns:
- The 16 bit checksum value needed.
- --*/
- {
- return (UINT16) (0x10000 - CalculateSum16 (Buffer, Size));
- }
- UINT16
- CalculateSum16 (
- IN UINT16 *Buffer,
- IN UINTN Size
- )
- /*++
- Routine Description:
- This function calculates the UINT16 sum for the requested region.
- Arguments:
- Buffer Pointer to buffer containing byte data of component.
- Size Size of the buffer
- Returns:
- The 16 bit checksum
- --*/
- {
- UINTN Index;
- UINT16 Sum;
- Sum = 0;
- //
- // Perform the word sum for buffer
- //
- for (Index = 0; Index < Size; Index++) {
- Sum = (UINT16) (Sum + Buffer[Index]);
- }
- return (UINT16) Sum;
- }
- EFI_STATUS
- PrintGuid (
- IN EFI_GUID *Guid
- )
- /*++
- Routine Description:
- This function prints a GUID to STDOUT.
- Arguments:
- Guid Pointer to a GUID to print.
- Returns:
- EFI_SUCCESS The GUID was printed.
- EFI_INVALID_PARAMETER The input was NULL.
- --*/
- {
- if (Guid == NULL) {
- Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
- return EFI_INVALID_PARAMETER;
- }
- printf (
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
- (unsigned) Guid->Data1,
- Guid->Data2,
- Guid->Data3,
- Guid->Data4[0],
- Guid->Data4[1],
- Guid->Data4[2],
- Guid->Data4[3],
- Guid->Data4[4],
- Guid->Data4[5],
- Guid->Data4[6],
- Guid->Data4[7]
- );
- return EFI_SUCCESS;
- }
- EFI_STATUS
- PrintGuidToBuffer (
- IN EFI_GUID *Guid,
- IN OUT UINT8 *Buffer,
- IN UINT32 BufferLen,
- IN BOOLEAN Uppercase
- )
- /*++
- Routine Description:
- This function prints a GUID to a buffer
- Arguments:
- Guid - Pointer to a GUID to print.
- Buffer - Pointer to a user-provided buffer to print to
- BufferLen - Size of the Buffer
- Uppercase - If use upper case.
- Returns:
- EFI_SUCCESS The GUID was printed.
- EFI_INVALID_PARAMETER The input was NULL.
- EFI_BUFFER_TOO_SMALL The input buffer was not big enough
- --*/
- {
- if (Guid == NULL) {
- Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
- return EFI_INVALID_PARAMETER;
- }
- if (BufferLen < PRINTED_GUID_BUFFER_SIZE) {
- Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with invalid buffer size");
- return EFI_BUFFER_TOO_SMALL;
- }
- if (Uppercase) {
- sprintf (
- (CHAR8 *)Buffer,
- "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
- (unsigned) Guid->Data1,
- Guid->Data2,
- Guid->Data3,
- Guid->Data4[0],
- Guid->Data4[1],
- Guid->Data4[2],
- Guid->Data4[3],
- Guid->Data4[4],
- Guid->Data4[5],
- Guid->Data4[6],
- Guid->Data4[7]
- );
- } else {
- sprintf (
- (CHAR8 *)Buffer,
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- (unsigned) Guid->Data1,
- Guid->Data2,
- Guid->Data3,
- Guid->Data4[0],
- Guid->Data4[1],
- Guid->Data4[2],
- Guid->Data4[3],
- Guid->Data4[4],
- Guid->Data4[5],
- Guid->Data4[6],
- Guid->Data4[7]
- );
- }
- return EFI_SUCCESS;
- }
- #ifdef __GNUC__
- size_t _filelength(int fd)
- {
- struct stat stat_buf;
- fstat(fd, &stat_buf);
- return stat_buf.st_size;
- }
- #ifndef __CYGWIN__
- char *strlwr(char *s)
- {
- char *p = s;
- for(;*s;s++) {
- *s = tolower(*s);
- }
- return p;
- }
- #endif
- #endif
- #define WINDOWS_EXTENSION_PATH "\\\\?\\"
- #define WINDOWS_UNC_EXTENSION_PATH "\\\\?\\UNC"
- //
- // Global data to store full file path. It is not required to be free.
- //
- CHAR8 mCommonLibFullPath[MAX_LONG_FILE_PATH];
- CHAR8 *
- LongFilePath (
- IN CHAR8 *FileName
- )
- /*++
- Routine Description:
- Convert FileName to the long file path, which can support larger than 260 length.
- Arguments:
- FileName - FileName.
- Returns:
- LongFilePath A pointer to the converted long file path.
- --*/
- {
- #ifdef __GNUC__
- //
- // __GNUC__ may not be good way to differentiate unix and windows. Need more investigation here.
- // unix has no limitation on file path. Just return FileName.
- //
- return FileName;
- #else
- CHAR8 *RootPath;
- CHAR8 *PathPointer;
- CHAR8 *NextPointer;
- PathPointer = (CHAR8 *) FileName;
- if (FileName != NULL) {
- //
- // Add the extension string first to support long file path.
- //
- mCommonLibFullPath[0] = 0;
- strcpy (mCommonLibFullPath, WINDOWS_EXTENSION_PATH);
- if (strlen (FileName) > 1 && FileName[0] == '\\' && FileName[1] == '\\') {
- //
- // network path like \\server\share to \\?\UNC\server\share
- //
- strcpy (mCommonLibFullPath, WINDOWS_UNC_EXTENSION_PATH);
- FileName ++;
- } else if (strlen (FileName) < 3 || FileName[1] != ':' || (FileName[2] != '\\' && FileName[2] != '/')) {
- //
- // Relative file path. Convert it to absolute path.
- //
- RootPath = getcwd (NULL, 0);
- if (RootPath != NULL) {
- if (strlen (mCommonLibFullPath) + strlen (RootPath) > MAX_LONG_FILE_PATH - 1) {
- Error (NULL, 0, 2000, "Invalid parameter", "RootPath is too long!");
- free (RootPath);
- return NULL;
- }
- strncat (mCommonLibFullPath, RootPath, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
- if (FileName[0] != '\\' && FileName[0] != '/') {
- if (strlen (mCommonLibFullPath) + 1 > MAX_LONG_FILE_PATH - 1) {
- Error (NULL, 0, 2000, "Invalid parameter", "RootPath is too long!");
- free (RootPath);
- return NULL;
- }
- //
- // Attach directory separator
- //
- strncat (mCommonLibFullPath, "\\", MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
- }
- free (RootPath);
- }
- }
- //
- // Construct the full file path
- //
- if (strlen (mCommonLibFullPath) + strlen (FileName) > MAX_LONG_FILE_PATH - 1) {
- Error (NULL, 0, 2000, "Invalid parameter", "FileName %s is too long!", FileName);
- return NULL;
- }
- strncat (mCommonLibFullPath, FileName, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
- //
- // Convert directory separator '/' to '\\'
- //
- PathPointer = (CHAR8 *) mCommonLibFullPath;
- do {
- if (*PathPointer == '/') {
- *PathPointer = '\\';
- }
- } while (*PathPointer ++ != '\0');
- //
- // Convert ":\\\\" to ":\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
- //
- if ((PathPointer = strstr (mCommonLibFullPath, ":\\\\")) != NULL) {
- *(PathPointer + 2) = '\0';
- strncat (mCommonLibFullPath, PathPointer + 3, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
- }
- //
- // Convert ".\\" to "", because it doesn't work with WINDOWS_EXTENSION_PATH.
- //
- while ((PathPointer = strstr (mCommonLibFullPath, ".\\")) != NULL) {
- *PathPointer = '\0';
- strncat (mCommonLibFullPath, PathPointer + 2, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
- }
- //
- // Convert "\\.\\" to "\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
- //
- while ((PathPointer = strstr (mCommonLibFullPath, "\\.\\")) != NULL) {
- *PathPointer = '\0';
- strncat (mCommonLibFullPath, PathPointer + 2, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
- }
- //
- // Convert "\\..\\" to last directory, because it doesn't work with WINDOWS_EXTENSION_PATH.
- //
- while ((PathPointer = strstr (mCommonLibFullPath, "\\..\\")) != NULL) {
- NextPointer = PathPointer + 3;
- do {
- PathPointer --;
- } while (PathPointer > mCommonLibFullPath && *PathPointer != ':' && *PathPointer != '\\');
- if (*PathPointer == '\\') {
- //
- // Skip one directory
- //
- *PathPointer = '\0';
- strncat (mCommonLibFullPath, NextPointer, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
- } else {
- //
- // No directory is found. Just break.
- //
- break;
- }
- }
- PathPointer = mCommonLibFullPath;
- }
- return PathPointer;
- #endif
- }
- CHAR16
- InternalCharToUpper (
- CHAR16 Char
- )
- {
- if (Char >= L'a' && Char <= L'z') {
- return (CHAR16) (Char - (L'a' - L'A'));
- }
- return Char;
- }
- UINTN
- StrnLenS (
- CONST CHAR16 *String,
- UINTN MaxSize
- )
- {
- UINTN Length;
- ASSERT (((UINTN) String & BIT0) == 0);
- //
- // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.
- //
- if ((String == NULL) || (MaxSize == 0)) {
- return 0;
- }
- Length = 0;
- while (String[Length] != 0) {
- if (Length >= MaxSize - 1) {
- return MaxSize;
- }
- Length++;
- }
- return Length;
- }
- VOID *
- InternalAllocatePool (
- UINTN AllocationSize
- )
- {
- VOID * Memory;
- Memory = malloc(AllocationSize);
- ASSERT(Memory != NULL);
- return Memory;
- }
- VOID *
- InternalReallocatePool (
- UINTN OldSize,
- UINTN NewSize,
- VOID *OldBuffer OPTIONAL
- )
- {
- VOID *NewBuffer;
- NewBuffer = AllocateZeroPool (NewSize);
- if (NewBuffer != NULL && OldBuffer != NULL) {
- memcpy (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
- free(OldBuffer);
- }
- return NewBuffer;
- }
- VOID *
- ReallocatePool (
- UINTN OldSize,
- UINTN NewSize,
- VOID *OldBuffer OPTIONAL
- )
- {
- return InternalReallocatePool (OldSize, NewSize, OldBuffer);
- }
- /**
- Returns the length of a Null-terminated Unicode string.
- This function returns the number of Unicode characters in the Null-terminated
- Unicode string specified by String.
- If String is NULL, then ASSERT().
- If String is not aligned on a 16-bit boundary, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and String contains more than
- PcdMaximumUnicodeStringLength Unicode characters, not including the
- Null-terminator, then ASSERT().
- @param String A pointer to a Null-terminated Unicode string.
- @return The length of String.
- **/
- UINTN
- StrLen (
- CONST CHAR16 *String
- )
- {
- UINTN Length;
- ASSERT (String != NULL);
- ASSERT (((UINTN) String & BIT0) == 0);
- for (Length = 0; *String != L'\0'; String++, Length++) {
- //
- // If PcdMaximumUnicodeStringLength is not zero,
- // length should not more than PcdMaximumUnicodeStringLength
- //
- }
- return Length;
- }
- BOOLEAN
- InternalSafeStringIsOverlap (
- IN VOID *Base1,
- IN UINTN Size1,
- IN VOID *Base2,
- IN UINTN Size2
- )
- {
- if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||
- (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) {
- return TRUE;
- }
- return FALSE;
- }
- BOOLEAN
- InternalSafeStringNoStrOverlap (
- IN CHAR16 *Str1,
- IN UINTN Size1,
- IN CHAR16 *Str2,
- IN UINTN Size2
- )
- {
- return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16));
- }
- /**
- Convert a Null-terminated Unicode decimal string to a value of type UINT64.
- This function outputs a value of type UINT64 by interpreting the contents of
- the Unicode string specified by String as a decimal number. The format of the
- input Unicode string String is:
- [spaces] [decimal digits].
- The valid decimal digit character is in the range [0-9]. The function will
- ignore the pad space, which includes spaces or tab characters, before
- [decimal digits]. The running zero in the beginning of [decimal digits] will
- be ignored. Then, the function stops at the first character that is a not a
- valid decimal character or a Null-terminator, whichever one comes first.
- If String is NULL, then ASSERT().
- If Data is NULL, then ASSERT().
- If String is not aligned in a 16-bit boundary, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and String contains more than
- PcdMaximumUnicodeStringLength Unicode characters, not including the
- Null-terminator, then ASSERT().
- If String has no valid decimal digits in the above format, then 0 is stored
- at the location pointed to by Data.
- If the number represented by String exceeds the range defined by UINT64, then
- MAX_UINT64 is stored at the location pointed to by Data.
- If EndPointer is not NULL, a pointer to the character that stopped the scan
- is stored at the location pointed to by EndPointer. If String has no valid
- decimal digits right after the optional pad spaces, the value of String is
- stored at the location pointed to by EndPointer.
- @param String Pointer to a Null-terminated Unicode string.
- @param EndPointer Pointer to character that stops scan.
- @param Data Pointer to the converted value.
- @retval RETURN_SUCCESS Value is translated from String.
- @retval RETURN_INVALID_PARAMETER If String is NULL.
- If Data is NULL.
- If PcdMaximumUnicodeStringLength is not
- zero, and String contains more than
- PcdMaximumUnicodeStringLength Unicode
- characters, not including the
- Null-terminator.
- @retval RETURN_UNSUPPORTED If the number represented by String exceeds
- the range defined by UINT64.
- **/
- RETURN_STATUS
- StrDecimalToUint64S (
- CONST CHAR16 *String,
- CHAR16 **EndPointer, OPTIONAL
- UINT64 *Data
- )
- {
- ASSERT (((UINTN) String & BIT0) == 0);
- //
- // 1. Neither String nor Data shall be a null pointer.
- //
- SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
- SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
- //
- // 2. The length of String shall not be greater than RSIZE_MAX.
- //
- if (RSIZE_MAX != 0) {
- SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
- }
- if (EndPointer != NULL) {
- *EndPointer = (CHAR16 *) String;
- }
- //
- // Ignore the pad spaces (space or tab)
- //
- while ((*String == L' ') || (*String == L'\t')) {
- String++;
- }
- //
- // Ignore leading Zeros after the spaces
- //
- while (*String == L'0') {
- String++;
- }
- *Data = 0;
- while (InternalIsDecimalDigitCharacter (*String)) {
- //
- // If the number represented by String overflows according to the range
- // defined by UINT64, then MAX_UINT64 is stored in *Data and
- // RETURN_UNSUPPORTED is returned.
- //
- if (*Data > ((MAX_UINT64 - (*String - L'0'))/10)) {
- *Data = MAX_UINT64;
- if (EndPointer != NULL) {
- *EndPointer = (CHAR16 *) String;
- }
- return RETURN_UNSUPPORTED;
- }
- *Data = (*Data) * 10 + (*String - L'0');
- String++;
- }
- if (EndPointer != NULL) {
- *EndPointer = (CHAR16 *) String;
- }
- return RETURN_SUCCESS;
- }
- /**
- Convert a Null-terminated Unicode hexadecimal string to a value of type
- UINT64.
- This function outputs a value of type UINT64 by interpreting the contents of
- the Unicode string specified by String as a hexadecimal number. The format of
- the input Unicode string String is:
- [spaces][zeros][x][hexadecimal digits].
- The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
- The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
- If "x" appears in the input string, it must be prefixed with at least one 0.
- The function will ignore the pad space, which includes spaces or tab
- characters, before [zeros], [x] or [hexadecimal digit]. The running zero
- before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
- after [x] or the first valid hexadecimal digit. Then, the function stops at
- the first character that is a not a valid hexadecimal character or NULL,
- whichever one comes first.
- If String is NULL, then ASSERT().
- If Data is NULL, then ASSERT().
- If String is not aligned in a 16-bit boundary, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and String contains more than
- PcdMaximumUnicodeStringLength Unicode characters, not including the
- Null-terminator, then ASSERT().
- If String has no valid hexadecimal digits in the above format, then 0 is
- stored at the location pointed to by Data.
- If the number represented by String exceeds the range defined by UINT64, then
- MAX_UINT64 is stored at the location pointed to by Data.
- If EndPointer is not NULL, a pointer to the character that stopped the scan
- is stored at the location pointed to by EndPointer. If String has no valid
- hexadecimal digits right after the optional pad spaces, the value of String
- is stored at the location pointed to by EndPointer.
- @param String Pointer to a Null-terminated Unicode string.
- @param EndPointer Pointer to character that stops scan.
- @param Data Pointer to the converted value.
- @retval RETURN_SUCCESS Value is translated from String.
- @retval RETURN_INVALID_PARAMETER If String is NULL.
- If Data is NULL.
- If PcdMaximumUnicodeStringLength is not
- zero, and String contains more than
- PcdMaximumUnicodeStringLength Unicode
- characters, not including the
- Null-terminator.
- @retval RETURN_UNSUPPORTED If the number represented by String exceeds
- the range defined by UINT64.
- **/
- RETURN_STATUS
- StrHexToUint64S (
- CONST CHAR16 *String,
- CHAR16 **EndPointer, OPTIONAL
- UINT64 *Data
- )
- {
- ASSERT (((UINTN) String & BIT0) == 0);
- //
- // 1. Neither String nor Data shall be a null pointer.
- //
- SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
- SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
- //
- // 2. The length of String shall not be greater than RSIZE_MAX.
- //
- if (RSIZE_MAX != 0) {
- SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
- }
- if (EndPointer != NULL) {
- *EndPointer = (CHAR16 *) String;
- }
- //
- // Ignore the pad spaces (space or tab)
- //
- while ((*String == L' ') || (*String == L'\t')) {
- String++;
- }
- //
- // Ignore leading Zeros after the spaces
- //
- while (*String == L'0') {
- String++;
- }
- if (InternalCharToUpper (*String) == L'X') {
- if (*(String - 1) != L'0') {
- *Data = 0;
- return RETURN_SUCCESS;
- }
- //
- // Skip the 'X'
- //
- String++;
- }
- *Data = 0;
- while (InternalIsHexaDecimalDigitCharacter (*String)) {
- //
- // If the number represented by String overflows according to the range
- // defined by UINT64, then MAX_UINT64 is stored in *Data and
- // RETURN_UNSUPPORTED is returned.
- //
- if (*Data > ((MAX_UINT64 - InternalHexCharToUintn (*String))>>4)) {
- *Data = MAX_UINT64;
- if (EndPointer != NULL) {
- *EndPointer = (CHAR16 *) String;
- }
- return RETURN_UNSUPPORTED;
- }
- *Data = ((*Data) << 4) + InternalHexCharToUintn (*String);
- String++;
- }
- if (EndPointer != NULL) {
- *EndPointer = (CHAR16 *) String;
- }
- return RETURN_SUCCESS;
- }
- UINT64
- StrDecimalToUint64 (
- CONST CHAR16 *String
- )
- {
- UINT64 Result;
- StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result);
- return Result;
- }
- UINT64
- StrHexToUint64 (
- CONST CHAR16 *String
- )
- {
- UINT64 Result;
- StrHexToUint64S (String, (CHAR16 **) NULL, &Result);
- return Result;
- }
- UINTN
- StrSize (
- CONST CHAR16 *String
- )
- {
- return (StrLen (String) + 1) * sizeof (*String);
- }
- UINT64
- ReadUnaligned64 (
- CONST UINT64 *Buffer
- )
- {
- ASSERT (Buffer != NULL);
- return *Buffer;
- }
- UINT64
- WriteUnaligned64 (
- UINT64 *Buffer,
- UINT64 Value
- )
- {
- ASSERT (Buffer != NULL);
- return *Buffer = Value;
- }
- EFI_GUID *
- CopyGuid (
- EFI_GUID *DestinationGuid,
- CONST EFI_GUID *SourceGuid
- )
- {
- WriteUnaligned64 (
- (UINT64*)DestinationGuid,
- ReadUnaligned64 ((CONST UINT64*)SourceGuid)
- );
- WriteUnaligned64 (
- (UINT64*)DestinationGuid + 1,
- ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)
- );
- return DestinationGuid;
- }
- UINT16
- SwapBytes16 (
- UINT16 Value
- )
- {
- return (UINT16) ((Value<< 8) | (Value>> 8));
- }
- UINT32
- SwapBytes32 (
- UINT32 Value
- )
- {
- UINT32 LowerBytes;
- UINT32 HigherBytes;
- LowerBytes = (UINT32) SwapBytes16 ((UINT16) Value);
- HigherBytes = (UINT32) SwapBytes16 ((UINT16) (Value >> 16));
- return (LowerBytes << 16 | HigherBytes);
- }
- BOOLEAN
- InternalIsDecimalDigitCharacter (
- CHAR16 Char
- )
- {
- return (BOOLEAN) (Char >= L'0' && Char <= L'9');
- }
- VOID *
- InternalAllocateCopyPool (
- UINTN AllocationSize,
- CONST VOID *Buffer
- )
- {
- VOID *Memory;
- ASSERT (Buffer != NULL);
- Memory = malloc (AllocationSize);
- if (Memory != NULL) {
- Memory = memcpy (Memory, Buffer, AllocationSize);
- }
- return Memory;
- }
- BOOLEAN
- InternalIsHexaDecimalDigitCharacter (
- CHAR16 Char
- )
- {
- return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) ||
- (Char >= L'A' && Char <= L'F') ||
- (Char >= L'a' && Char <= L'f'));
- }
- UINTN
- InternalHexCharToUintn (
- CHAR16 Char
- )
- {
- if (InternalIsDecimalDigitCharacter (Char)) {
- return Char - L'0';
- }
- return (10 + InternalCharToUpper (Char) - L'A');
- }
- /**
- Convert a Null-terminated Unicode hexadecimal string to a byte array.
- This function outputs a byte array by interpreting the contents of
- the Unicode string specified by String in hexadecimal format. The format of
- the input Unicode string String is:
- [XX]*
- X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
- The function decodes every two hexadecimal digit characters as one byte. The
- decoding stops after Length of characters and outputs Buffer containing
- (Length / 2) bytes.
- If String is not aligned in a 16-bit boundary, then ASSERT().
- If String is NULL, then ASSERT().
- If Buffer is NULL, then ASSERT().
- If Length is not multiple of 2, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero and Length is greater than
- PcdMaximumUnicodeStringLength, then ASSERT().
- If MaxBufferSize is less than (Length / 2), then ASSERT().
- @param String Pointer to a Null-terminated Unicode string.
- @param Length The number of Unicode characters to decode.
- @param Buffer Pointer to the converted bytes array.
- @param MaxBufferSize The maximum size of Buffer.
- @retval RETURN_SUCCESS Buffer is translated from String.
- @retval RETURN_INVALID_PARAMETER If String is NULL.
- If Data is NULL.
- If Length is not multiple of 2.
- If PcdMaximumUnicodeStringLength is not zero,
- and Length is greater than
- PcdMaximumUnicodeStringLength.
- @retval RETURN_UNSUPPORTED If Length of characters from String contain
- a character that is not valid hexadecimal
- digit characters, or a Null-terminator.
- @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
- **/
- RETURN_STATUS
- StrHexToBytes (
- CONST CHAR16 *String,
- UINTN Length,
- UINT8 *Buffer,
- UINTN MaxBufferSize
- )
- {
- UINTN Index;
- ASSERT (((UINTN) String & BIT0) == 0);
- //
- // 1. None of String or Buffer shall be a null pointer.
- //
- SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
- SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
- //
- // 2. Length shall not be greater than RSIZE_MAX.
- //
- if (RSIZE_MAX != 0) {
- SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
- }
- //
- // 3. Length shall not be odd.
- //
- SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
- //
- // 4. MaxBufferSize shall equal to or greater than Length / 2.
- //
- SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
- //
- // 5. String shall not contains invalid hexadecimal digits.
- //
- for (Index = 0; Index < Length; Index++) {
- if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {
- break;
- }
- }
- if (Index != Length) {
- return RETURN_UNSUPPORTED;
- }
- //
- // Convert the hex string to bytes.
- //
- for(Index = 0; Index < Length; Index++) {
- //
- // For even characters, write the upper nibble for each buffer byte,
- // and for even characters, the lower nibble.
- //
- if ((Index & BIT0) == 0) {
- Buffer[Index / 2] = (UINT8) InternalHexCharToUintn (String[Index]) << 4;
- } else {
- Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]);
- }
- }
- return RETURN_SUCCESS;
- }
- /**
- Convert a Null-terminated Unicode GUID string to a value of type
- EFI_GUID.
- This function outputs a GUID value by interpreting the contents of
- the Unicode string specified by String. The format of the input
- Unicode string String consists of 36 characters, as follows:
- aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
- The pairs aa - pp are two characters in the range [0-9], [a-f] and
- [A-F], with each pair representing a single byte hexadecimal value.
- The mapping between String and the EFI_GUID structure is as follows:
- aa Data1[24:31]
- bb Data1[16:23]
- cc Data1[8:15]
- dd Data1[0:7]
- ee Data2[8:15]
- ff Data2[0:7]
- gg Data3[8:15]
- hh Data3[0:7]
- ii Data4[0:7]
- jj Data4[8:15]
- kk Data4[16:23]
- ll Data4[24:31]
- mm Data4[32:39]
- nn Data4[40:47]
- oo Data4[48:55]
- pp Data4[56:63]
- If String is NULL, then ASSERT().
- If Guid is NULL, then ASSERT().
- If String is not aligned in a 16-bit boundary, then ASSERT().
- @param String Pointer to a Null-terminated Unicode string.
- @param Guid Pointer to the converted GUID.
- @retval RETURN_SUCCESS Guid is translated from String.
- @retval RETURN_INVALID_PARAMETER If String is NULL.
- If Data is NULL.
- @retval RETURN_UNSUPPORTED If String is not as the above format.
- **/
- RETURN_STATUS
- StrToGuid (
- CONST CHAR16 *String,
- EFI_GUID *Guid
- )
- {
- RETURN_STATUS Status;
- EFI_GUID LocalGuid;
- ASSERT (((UINTN) String & BIT0) == 0);
- //
- // 1. None of String or Guid shall be a null pointer.
- //
- SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
- SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
- //
- // Get aabbccdd in big-endian.
- //
- Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1));
- if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') {
- return RETURN_UNSUPPORTED;
- }
- //
- // Convert big-endian to little-endian.
- //
- LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
- String += 2 * sizeof (LocalGuid.Data1) + 1;
- //
- // Get eeff in big-endian.
- //
- Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2));
- if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') {
- return RETURN_UNSUPPORTED;
- }
- //
- // Convert big-endian to little-endian.
- //
- LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
- String += 2 * sizeof (LocalGuid.Data2) + 1;
- //
- // Get gghh in big-endian.
- //
- Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3));
- if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') {
- return RETURN_UNSUPPORTED;
- }
- //
- // Convert big-endian to little-endian.
- //
- LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
- String += 2 * sizeof (LocalGuid.Data3) + 1;
- //
- // Get iijj.
- //
- Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
- if (RETURN_ERROR (Status) || String[2 * 2] != L'-') {
- return RETURN_UNSUPPORTED;
- }
- String += 2 * 2 + 1;
- //
- // Get kkllmmnnoopp.
- //
- Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
- if (RETURN_ERROR (Status)) {
- return RETURN_UNSUPPORTED;
- }
- CopyGuid (Guid, &LocalGuid);
- return RETURN_SUCCESS;
- }
- /**
- Compares up to a specified length the contents of two Null-terminated Unicode strings,
- and returns the difference between the first mismatched Unicode characters.
- This function compares the Null-terminated Unicode string FirstString to the
- Null-terminated Unicode string SecondString. At most, Length Unicode
- characters will be compared. If Length is 0, then 0 is returned. If
- FirstString is identical to SecondString, then 0 is returned. Otherwise, the
- value returned is the first mismatched Unicode character in SecondString
- subtracted from the first mismatched Unicode character in FirstString.
- If Length > 0 and FirstString is NULL, then ASSERT().
- If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
- If Length > 0 and SecondString is NULL, then ASSERT().
- If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
- PcdMaximumUnicodeStringLength, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
- PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
- then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
- PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
- then ASSERT().
- @param FirstString A pointer to a Null-terminated Unicode string.
- @param SecondString A pointer to a Null-terminated Unicode string.
- @param Length The maximum number of Unicode characters to compare.
- @retval 0 FirstString is identical to SecondString.
- @return others FirstString is not identical to SecondString.
- **/
- INTN
- StrnCmp (
- CONST CHAR16 *FirstString,
- CONST CHAR16 *SecondString,
- UINTN Length
- )
- {
- if (Length == 0) {
- return 0;
- }
- //
- // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
- // Length tests are performed inside StrLen().
- //
- ASSERT (StrSize (FirstString) != 0);
- ASSERT (StrSize (SecondString) != 0);
- while ((*FirstString != L'\0') &&
- (*SecondString != L'\0') &&
- (*FirstString == *SecondString) &&
- (Length > 1)) {
- FirstString++;
- SecondString++;
- Length--;
- }
- return *FirstString - *SecondString;
- }
- VOID *
- AllocateCopyPool (
- UINTN AllocationSize,
- CONST VOID *Buffer
- )
- {
- return InternalAllocateCopyPool (AllocationSize, Buffer);
- }
- INTN
- StrCmp (
- CONST CHAR16 *FirstString,
- CONST CHAR16 *SecondString
- )
- {
- //
- // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
- //
- ASSERT (StrSize (FirstString) != 0);
- ASSERT (StrSize (SecondString) != 0);
- while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
- FirstString++;
- SecondString++;
- }
- return *FirstString - *SecondString;
- }
- UINT64
- SwapBytes64 (
- UINT64 Value
- )
- {
- return InternalMathSwapBytes64 (Value);
- }
- UINT64
- InternalMathSwapBytes64 (
- UINT64 Operand
- )
- {
- UINT64 LowerBytes;
- UINT64 HigherBytes;
- LowerBytes = (UINT64) SwapBytes32 ((UINT32) Operand);
- HigherBytes = (UINT64) SwapBytes32 ((UINT32) (Operand >> 32));
- return (LowerBytes << 32 | HigherBytes);
- }
- RETURN_STATUS
- StrToIpv4Address (
- CONST CHAR16 *String,
- CHAR16 **EndPointer,
- EFI_IPv4_ADDRESS *Address,
- UINT8 *PrefixLength
- )
- {
- RETURN_STATUS Status;
- UINTN AddressIndex;
- UINT64 Uint64;
- EFI_IPv4_ADDRESS LocalAddress;
- UINT8 LocalPrefixLength;
- CHAR16 *Pointer;
- LocalPrefixLength = MAX_UINT8;
- LocalAddress.Addr[0] = 0;
- ASSERT (((UINTN) String & BIT0) == 0);
- //
- // 1. None of String or Guid shall be a null pointer.
- //
- SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
- SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
- for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
- if (!InternalIsDecimalDigitCharacter (*Pointer)) {
- //
- // D or P contains invalid characters.
- //
- break;
- }
- //
- // Get D or P.
- //
- Status = StrDecimalToUint64S ((CONST CHAR16 *) Pointer, &Pointer, &Uint64);
- if (RETURN_ERROR (Status)) {
- return RETURN_UNSUPPORTED;
- }
- if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
- //
- // It's P.
- //
- if (Uint64 > 32) {
- return RETURN_UNSUPPORTED;
- }
- LocalPrefixLength = (UINT8) Uint64;
- } else {
- //
- // It's D.
- //
- if (Uint64 > MAX_UINT8) {
- return RETURN_UNSUPPORTED;
- }
- LocalAddress.Addr[AddressIndex] = (UINT8) Uint64;
- AddressIndex++;
- }
- //
- // Check the '.' or '/', depending on the AddressIndex.
- //
- if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
- if (*Pointer == L'/') {
- //
- // '/P' is in the String.
- // Skip "/" and get P in next loop.
- //
- Pointer++;
- } else {
- //
- // '/P' is not in the String.
- //
- break;
- }
- } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
- if (*Pointer == L'.') {
- //
- // D should be followed by '.'
- //
- Pointer++;
- } else {
- return RETURN_UNSUPPORTED;
- }
- }
- }
- if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
- return RETURN_UNSUPPORTED;
- }
- memcpy (Address, &LocalAddress, sizeof (*Address));
- if (PrefixLength != NULL) {
- *PrefixLength = LocalPrefixLength;
- }
- if (EndPointer != NULL) {
- *EndPointer = Pointer;
- }
- return RETURN_SUCCESS;
- }
- RETURN_STATUS
- StrToIpv6Address (
- CONST CHAR16 *String,
- CHAR16 **EndPointer,
- EFI_IPv6_ADDRESS *Address,
- UINT8 *PrefixLength
- )
- {
- RETURN_STATUS Status;
- UINTN AddressIndex;
- UINT64 Uint64;
- EFI_IPv6_ADDRESS LocalAddress;
- UINT8 LocalPrefixLength;
- CONST CHAR16 *Pointer;
- CHAR16 *End;
- UINTN CompressStart;
- BOOLEAN ExpectPrefix;
- LocalPrefixLength = MAX_UINT8;
- CompressStart = ARRAY_SIZE (Address->Addr);
- ExpectPrefix = FALSE;
- ASSERT (((UINTN) String & BIT0) == 0);
- //
- // 1. None of String or Guid shall be a null pointer.
- //
- SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
- SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
- for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
- if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
- if (*Pointer != L':') {
- //
- // ":" or "/" should be followed by digit characters.
- //
- return RETURN_UNSUPPORTED;
- }
- //
- // Meet second ":" after previous ":" or "/"
- // or meet first ":" in the beginning of String.
- //
- if (ExpectPrefix) {
- //
- // ":" shall not be after "/"
- //
- return RETURN_UNSUPPORTED;
- }
- if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) {
- //
- // "::" can only appear once.
- // "::" can only appear when address is not full length.
- //
- return RETURN_UNSUPPORTED;
- } else {
- //
- // Remember the start of zero compressing.
- //
- CompressStart = AddressIndex;
- Pointer++;
- if (CompressStart == 0) {
- if (*Pointer != L':') {
- //
- // Single ":" shall not be in the beginning of String.
- //
- return RETURN_UNSUPPORTED;
- }
- Pointer++;
- }
- }
- }
- if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
- if (*Pointer == L'/') {
- //
- // Might be optional "/P" after "::".
- //
- if (CompressStart != AddressIndex) {
- return RETURN_UNSUPPORTED;
- }
- } else {
- break;
- }
- } else {
- if (!ExpectPrefix) {
- //
- // Get X.
- //
- Status = StrHexToUint64S (Pointer, &End, &Uint64);
- if (RETURN_ERROR (Status) || End - Pointer > 4) {
- //
- // Number of hexadecimal digit characters is no more than 4.
- //
- return RETURN_UNSUPPORTED;
- }
- Pointer = End;
- //
- // Uint64 won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
- //
- ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));
- LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uint64 >> 8);
- LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uint64;
- AddressIndex += 2;
- } else {
- //
- // Get P, then exit the loop.
- //
- Status = StrDecimalToUint64S (Pointer, &End, &Uint64);
- if (RETURN_ERROR (Status) || End == Pointer || Uint64 > 128) {
- //
- // Prefix length should not exceed 128.
- //
- return RETURN_UNSUPPORTED;
- }
- LocalPrefixLength = (UINT8) Uint64;
- Pointer = End;
- break;
- }
- }
- //
- // Skip ':' or "/"
- //
- if (*Pointer == L'/') {
- ExpectPrefix = TRUE;
- } else if (*Pointer == L':') {
- if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
- //
- // Meet additional ":" after all 8 16-bit address
- //
- break;
- }
- } else {
- //
- // Meet other character that is not "/" or ":" after all 8 16-bit address
- //
- break;
- }
- Pointer++;
- }
- if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) ||
- (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr))
- ) {
- //
- // Full length of address shall not have compressing zeros.
- // Non-full length of address shall have compressing zeros.
- //
- return RETURN_UNSUPPORTED;
- }
- memcpy (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
- if (AddressIndex > CompressStart) {
- memset (&Address->Addr[CompressStart], 0, ARRAY_SIZE (Address->Addr) - AddressIndex);
- memcpy (
- &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
- &LocalAddress.Addr[CompressStart],
- AddressIndex - CompressStart
- );
- }
- if (PrefixLength != NULL) {
- *PrefixLength = LocalPrefixLength;
- }
- if (EndPointer != NULL) {
- *EndPointer = (CHAR16 *) Pointer;
- }
- return RETURN_SUCCESS;
- }
- RETURN_STATUS
- UnicodeStrToAsciiStrS (
- CONST CHAR16 *Source,
- CHAR8 *Destination,
- UINTN DestMax
- )
- {
- UINTN SourceLen;
- ASSERT (((UINTN) Source & BIT0) == 0);
- //
- // 1. Neither Destination nor Source shall be a null pointer.
- //
- SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
- SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
- //
- // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
- //
- if (ASCII_RSIZE_MAX != 0) {
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
- }
- if (RSIZE_MAX != 0) {
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
- }
- //
- // 3. DestMax shall not equal zero.
- //
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
- //
- // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
- //
- SourceLen = StrnLenS (Source, DestMax);
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
- //
- // 5. Copying shall not take place between objects that overlap.
- //
- SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);
- //
- // convert string
- //
- while (*Source != '\0') {
- //
- // If any Unicode characters in Source contain
- // non-zero value in the upper 8 bits, then ASSERT().
- //
- ASSERT (*Source < 0x100);
- *(Destination++) = (CHAR8) *(Source++);
- }
- *Destination = '\0';
- return RETURN_SUCCESS;
- }
- RETURN_STATUS
- StrCpyS (
- CHAR16 *Destination,
- UINTN DestMax,
- CONST CHAR16 *Source
- )
- {
- UINTN SourceLen;
- ASSERT (((UINTN) Destination & BIT0) == 0);
- ASSERT (((UINTN) Source & BIT0) == 0);
- //
- // 1. Neither Destination nor Source shall be a null pointer.
- //
- SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
- SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
- //
- // 2. DestMax shall not be greater than RSIZE_MAX.
- //
- if (RSIZE_MAX != 0) {
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
- }
- //
- // 3. DestMax shall not equal zero.
- //
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
- //
- // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
- //
- SourceLen = StrnLenS (Source, DestMax);
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
- //
- // 5. Copying shall not take place between objects that overlap.
- //
- SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
- //
- // The StrCpyS function copies the string pointed to by Source (including the terminating
- // null character) into the array pointed to by Destination.
- //
- while (*Source != 0) {
- *(Destination++) = *(Source++);
- }
- *Destination = 0;
- return RETURN_SUCCESS;
- }
- VOID *
- AllocateZeroPool (
- UINTN AllocationSize
- )
- {
- VOID * Memory;
- Memory = malloc(AllocationSize);
- ASSERT (Memory != NULL);
- if (Memory == NULL) {
- fprintf(stderr, "Not memory for malloc\n");
- }
- memset(Memory, 0, AllocationSize);
- return Memory;
- }
- VOID *
- AllocatePool (
- UINTN AllocationSize
- )
- {
- return InternalAllocatePool (AllocationSize);
- }
- UINT16
- WriteUnaligned16 (
- UINT16 *Buffer,
- UINT16 Value
- )
- {
- ASSERT (Buffer != NULL);
- return *Buffer = Value;
- }
- UINT16
- ReadUnaligned16 (
- CONST UINT16 *Buffer
- )
- {
- ASSERT (Buffer != NULL);
- return *Buffer;
- }
- /**
- Return whether the integer string is a hex string.
- @param Str The integer string
- @retval TRUE Hex string
- @retval FALSE Decimal string
- **/
- BOOLEAN
- IsHexStr (
- CHAR16 *Str
- )
- {
- //
- // skip preceding white space
- //
- while ((*Str != 0) && *Str == L' ') {
- Str ++;
- }
- //
- // skip preceding zeros
- //
- while ((*Str != 0) && *Str == L'0') {
- Str ++;
- }
- return (BOOLEAN) (*Str == L'x' || *Str == L'X');
- }
- /**
- Convert integer string to uint.
- @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
- @return A UINTN value represented by Str
- **/
- UINTN
- Strtoi (
- CHAR16 *Str
- )
- {
- if (IsHexStr (Str)) {
- return (UINTN)StrHexToUint64 (Str);
- } else {
- return (UINTN)StrDecimalToUint64 (Str);
- }
- }
- /**
- Convert integer string to 64 bit data.
- @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
- @param Data A pointer to the UINT64 value represented by Str
- **/
- VOID
- Strtoi64 (
- CHAR16 *Str,
- UINT64 *Data
- )
- {
- if (IsHexStr (Str)) {
- *Data = StrHexToUint64 (Str);
- } else {
- *Data = StrDecimalToUint64 (Str);
- }
- }
- /**
- Converts a Unicode string to ASCII string.
- @param Str The equivalent Unicode string
- @param AsciiStr On input, it points to destination ASCII string buffer; on output, it points
- to the next ASCII string next to it
- **/
- VOID
- StrToAscii (
- CHAR16 *Str,
- CHAR8 **AsciiStr
- )
- {
- CHAR8 *Dest;
- Dest = *AsciiStr;
- while (!IS_NULL (*Str)) {
- *(Dest++) = (CHAR8) *(Str++);
- }
- *Dest = 0;
- //
- // Return the string next to it
- //
- *AsciiStr = Dest + 1;
- }
- /**
- Gets current sub-string from a string list, before return
- the list header is moved to next sub-string. The sub-string is separated
- by the specified character. For example, the separator is ',', the string
- list is "2,0,3", it returns "2", the remain list move to "0,3"
- @param List A string list separated by the specified separator
- @param Separator The separator character
- @return A pointer to the current sub-string
- **/
- CHAR16 *
- SplitStr (
- CHAR16 **List,
- CHAR16 Separator
- )
- {
- CHAR16 *Str;
- CHAR16 *ReturnStr;
- Str = *List;
- ReturnStr = Str;
- if (IS_NULL (*Str)) {
- return ReturnStr;
- }
- //
- // Find first occurrence of the separator
- //
- while (!IS_NULL (*Str)) {
- if (*Str == Separator) {
- break;
- }
- Str++;
- }
- if (*Str == Separator) {
- //
- // Find a sub-string, terminate it
- //
- *Str = L'\0';
- Str++;
- }
- //
- // Move to next sub-string
- //
- *List = Str;
- return ReturnStr;
- }
|