2 Common basic Library Functions
4 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
24 #include "CommonLib.h"
25 #include "EfiUtilityMsgs.h"
36 Set Buffer to zero for Size bytes.
40 Buffer - Memory to set.
42 Size - Number of bytes to set
68 Copy Length bytes from Source to Destination.
72 Destination - Target of copy
74 Source - Place to copy from
76 Length - Number of bytes to copy
87 Destination8
= Destination
;
90 *(Destination8
++) = *(Source8
++);
100 PeiZeroMem (Buffer
, Size
);
105 IN VOID
*Destination
,
110 PeiCopyMem (Destination
, Source
, Length
);
126 Guid1 - guid to compare
127 Guid2 - guid to compare
130 = 0 if Guid1 == Guid2
131 != 0 if Guid1 != Guid2
140 // Compare 32 bits at a time
142 g1
= (INT32
*) Guid1
;
143 g2
= (INT32
*) Guid2
;
156 IN CHAR8
*InputFileName
,
157 OUT CHAR8
**InputFileImage
,
158 OUT UINT32
*BytesRead
164 This function opens a file and reads it into a memory buffer. The function
165 will allocate the memory buffer and returns the size of the buffer.
169 InputFileName The name of the file to read.
170 InputFileImage A pointer to the memory buffer.
171 BytesRead The size of the memory buffer.
175 EFI_SUCCESS The function completed successfully.
176 EFI_INVALID_PARAMETER One of the input parameters was invalid.
177 EFI_ABORTED An error occurred.
178 EFI_OUT_OF_RESOURCES No resource to complete operations.
186 // Verify input parameters.
188 if (InputFileName
== NULL
|| strlen (InputFileName
) == 0 || InputFileImage
== NULL
) {
189 return EFI_INVALID_PARAMETER
;
192 // Open the file and copy contents into a memory buffer.
197 InputFile
= fopen (LongFilePath (InputFileName
), "rb");
198 if (InputFile
== NULL
) {
199 Error (NULL
, 0, 0001, "Error opening the input file", InputFileName
);
203 // Go to the end so that we can determine the file size
205 if (fseek (InputFile
, 0, SEEK_END
)) {
206 Error (NULL
, 0, 0004, "Error reading the input file", InputFileName
);
213 FileSize
= ftell (InputFile
);
214 if (FileSize
== -1) {
215 Error (NULL
, 0, 0003, "Error parsing the input file", InputFileName
);
222 *InputFileImage
= malloc (FileSize
);
223 if (*InputFileImage
== NULL
) {
225 return EFI_OUT_OF_RESOURCES
;
228 // Reset to the beginning of the file
230 if (fseek (InputFile
, 0, SEEK_SET
)) {
231 Error (NULL
, 0, 0004, "Error reading the input file", InputFileName
);
233 free (*InputFileImage
);
234 *InputFileImage
= NULL
;
238 // Read all of the file contents.
240 *BytesRead
= fread (*InputFileImage
, sizeof (UINT8
), FileSize
, InputFile
);
241 if (*BytesRead
!= sizeof (UINT8
) * FileSize
) {
242 Error (NULL
, 0, 0004, "Error reading the input file", InputFileName
);
244 free (*InputFileImage
);
245 *InputFileImage
= NULL
;
258 IN CHAR8
*OutputFileName
,
259 IN CHAR8
*OutputFileImage
,
260 IN UINT32 BytesToWrite
266 This function opens a file and writes OutputFileImage into the file.
270 OutputFileName The name of the file to write.
271 OutputFileImage A pointer to the memory buffer.
272 BytesToWrite The size of the memory buffer.
276 EFI_SUCCESS The function completed successfully.
277 EFI_INVALID_PARAMETER One of the input parameters was invalid.
278 EFI_ABORTED An error occurred.
279 EFI_OUT_OF_RESOURCES No resource to complete operations.
287 // Verify input parameters.
289 if (OutputFileName
== NULL
|| strlen (OutputFileName
) == 0 || OutputFileImage
== NULL
) {
290 return EFI_INVALID_PARAMETER
;
293 // Open the file and copy contents into a memory buffer.
298 OutputFile
= fopen (LongFilePath (OutputFileName
), "wb");
299 if (OutputFile
== NULL
) {
300 Error (NULL
, 0, 0001, "Error opening the output file", OutputFileName
);
305 // Write all of the file contents.
307 BytesWrote
= fwrite (OutputFileImage
, sizeof (UINT8
), BytesToWrite
, OutputFile
);
308 if (BytesWrote
!= sizeof (UINT8
) * BytesToWrite
) {
309 Error (NULL
, 0, 0002, "Error writing the output file", OutputFileName
);
330 This function calculates the value needed for a valid UINT8 checksum
334 Buffer Pointer to buffer containing byte data of component.
335 Size Size of the buffer
339 The 8 bit checksum value needed.
343 return (UINT8
) (0x100 - CalculateSum8 (Buffer
, Size
));
353 Routine Description::
355 This function calculates the UINT8 sum for the requested region.
359 Buffer Pointer to buffer containing byte data of component.
360 Size Size of the buffer
364 The 8 bit checksum value needed.
374 // Perform the byte sum for buffer
376 for (Index
= 0; Index
< Size
; Index
++) {
377 Sum
= (UINT8
) (Sum
+ Buffer
[Index
]);
384 CalculateChecksum16 (
390 Routine Description::
392 This function calculates the value needed for a valid UINT16 checksum
396 Buffer Pointer to buffer containing byte data of component.
397 Size Size of the buffer
401 The 16 bit checksum value needed.
405 return (UINT16
) (0x10000 - CalculateSum16 (Buffer
, Size
));
417 This function calculates the UINT16 sum for the requested region.
421 Buffer Pointer to buffer containing byte data of component.
422 Size Size of the buffer
436 // Perform the word sum for buffer
438 for (Index
= 0; Index
< Size
; Index
++) {
439 Sum
= (UINT16
) (Sum
+ Buffer
[Index
]);
453 This function prints a GUID to STDOUT.
457 Guid Pointer to a GUID to print.
461 EFI_SUCCESS The GUID was printed.
462 EFI_INVALID_PARAMETER The input was NULL.
467 Error (NULL
, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
468 return EFI_INVALID_PARAMETER
;
472 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
473 (unsigned) Guid
->Data1
,
491 IN OUT UINT8
*Buffer
,
499 This function prints a GUID to a buffer
503 Guid - Pointer to a GUID to print.
504 Buffer - Pointer to a user-provided buffer to print to
505 BufferLen - Size of the Buffer
506 Uppercase - If use upper case.
510 EFI_SUCCESS The GUID was printed.
511 EFI_INVALID_PARAMETER The input was NULL.
512 EFI_BUFFER_TOO_SMALL The input buffer was not big enough
517 Error (NULL
, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
518 return EFI_INVALID_PARAMETER
;
521 if (BufferLen
< PRINTED_GUID_BUFFER_SIZE
) {
522 Error (NULL
, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with invalid buffer size");
523 return EFI_BUFFER_TOO_SMALL
;
529 "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
530 (unsigned) Guid
->Data1
,
545 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
546 (unsigned) Guid
->Data1
,
565 size_t _filelength(int fd
)
567 struct stat stat_buf
;
568 fstat(fd
, &stat_buf
);
569 return stat_buf
.st_size
;
573 char *strlwr(char *s
)
584 #define WINDOWS_EXTENSION_PATH "\\\\?\\"
585 #define WINDOWS_UNC_EXTENSION_PATH "\\\\?\\UNC"
588 // Global data to store full file path. It is not required to be free.
590 CHAR8 mCommonLibFullPath
[MAX_LONG_FILE_PATH
];
599 Convert FileName to the long file path, which can support larger than 260 length.
605 LongFilePath A pointer to the converted long file path.
611 // __GNUC__ may not be good way to differentiate unix and windows. Need more investigation here.
612 // unix has no limitation on file path. Just return FileName.
620 PathPointer
= (CHAR8
*) FileName
;
622 if (FileName
!= NULL
) {
624 // Add the extension string first to support long file path.
626 mCommonLibFullPath
[0] = 0;
627 strcpy (mCommonLibFullPath
, WINDOWS_EXTENSION_PATH
);
629 if (strlen (FileName
) > 1 && FileName
[0] == '\\' && FileName
[1] == '\\') {
631 // network path like \\server\share to \\?\UNC\server\share
633 strcpy (mCommonLibFullPath
, WINDOWS_UNC_EXTENSION_PATH
);
635 } else if (strlen (FileName
) < 3 || FileName
[1] != ':' || (FileName
[2] != '\\' && FileName
[2] != '/')) {
637 // Relative file path. Convert it to absolute path.
639 RootPath
= getcwd (NULL
, 0);
640 if (RootPath
!= NULL
) {
641 strcat (mCommonLibFullPath
, RootPath
);
642 if (FileName
[0] != '\\' && FileName
[0] != '/') {
644 // Attach directory separator
646 strcat (mCommonLibFullPath
, "\\");
653 // Construct the full file path
655 if (strlen (mCommonLibFullPath
) + strlen (FileName
) > MAX_LONG_FILE_PATH
- 1) {
656 Error (NULL
, 0, 2000, "Invalid parameter", "FileName %s is too long!", FileName
);
659 strncat (mCommonLibFullPath
, FileName
, MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
662 // Convert directory separator '/' to '\\'
664 PathPointer
= (CHAR8
*) mCommonLibFullPath
;
666 if (*PathPointer
== '/') {
669 } while (*PathPointer
++ != '\0');
672 // Convert ":\\\\" to ":\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
674 if ((PathPointer
= strstr (mCommonLibFullPath
, ":\\\\")) != NULL
) {
675 *(PathPointer
+ 2) = '\0';
676 strcat (mCommonLibFullPath
, PathPointer
+ 3);
680 // Convert ".\\" to "", because it doesn't work with WINDOWS_EXTENSION_PATH.
682 while ((PathPointer
= strstr (mCommonLibFullPath
, ".\\")) != NULL
) {
684 strcat (mCommonLibFullPath
, PathPointer
+ 2);
688 // Convert "\\.\\" to "\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
690 while ((PathPointer
= strstr (mCommonLibFullPath
, "\\.\\")) != NULL
) {
692 strcat (mCommonLibFullPath
, PathPointer
+ 2);
696 // Convert "\\..\\" to last directory, because it doesn't work with WINDOWS_EXTENSION_PATH.
698 while ((PathPointer
= strstr (mCommonLibFullPath
, "\\..\\")) != NULL
) {
699 NextPointer
= PathPointer
+ 3;
702 } while (PathPointer
> mCommonLibFullPath
&& *PathPointer
!= ':' && *PathPointer
!= '\\');
704 if (*PathPointer
== '\\') {
706 // Skip one directory
709 strcat (mCommonLibFullPath
, NextPointer
);
712 // No directory is found. Just break.
718 PathPointer
= mCommonLibFullPath
;