1 /** @file 2 This contains some useful functions for accessing files. 3 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 9 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. 12 13 **/ 14 15 #include <assert.h> 16 #include <string.h> 17 #include <ctype.h> 18 #include <stdlib.h> 19 #include "CommonLib.h" 20 #include "MemoryFile.h" 21 22 23 // 24 // Local (static) function prototypes 25 // 26 STATIC 27 VOID 28 CheckMemoryFileState ( 29 IN EFI_HANDLE InputMemoryFile 30 ); 31 32 // 33 // Function implementations 34 // 35 36 EFI_STATUS 37 GetMemoryFile ( 38 IN CHAR8 *InputFileName, 39 OUT EFI_HANDLE *OutputMemoryFile 40 ) 41 /*++ 42 43 Routine Description: 44 45 This opens a file, reads it into memory and returns a memory file 46 object. 47 48 Arguments: 49 50 InputFile Memory file image. 51 OutputMemoryFile Handle to memory file 52 53 Returns: 54 55 EFI_STATUS 56 OutputMemoryFile is valid if !EFI_ERROR 57 58 --*/ 59 { 60 EFI_STATUS Status; 61 CHAR8 *InputFileImage; 62 UINT32 BytesRead; 63 MEMORY_FILE *NewMemoryFile; 64 65 Status = GetFileImage (InputFileName, &InputFileImage, &BytesRead); 66 if (EFI_ERROR (Status)) { 67 return Status; 68 } 69 70 NewMemoryFile = malloc (sizeof (*NewMemoryFile)); 71 if (NewMemoryFile == NULL) { 72 free (InputFileImage); 73 return EFI_OUT_OF_RESOURCES; 74 } 75 76 NewMemoryFile->FileImage = InputFileImage; 77 NewMemoryFile->CurrentFilePointer = InputFileImage; 78 NewMemoryFile->Eof = InputFileImage + BytesRead; 79 80 *OutputMemoryFile = (EFI_HANDLE)NewMemoryFile; 81 82 CheckMemoryFileState (*OutputMemoryFile); 83 84 return EFI_SUCCESS; 85 } 86 87 88 EFI_STATUS 89 FreeMemoryFile ( 90 IN EFI_HANDLE InputMemoryFile 91 ) 92 /*++ 93 94 Routine Description: 95 96 Frees all memory associated with the input memory file. 97 98 Arguments: 99 100 InputMemoryFile Handle to memory file 101 102 Returns: 103 104 EFI_STATUS 105 106 --*/ 107 { 108 MEMORY_FILE *MemoryFile; 109 110 CheckMemoryFileState (InputMemoryFile); 111 112 MemoryFile = (MEMORY_FILE*)InputMemoryFile; 113 114 free (MemoryFile->FileImage); 115 116 // 117 // Invalidate state of MEMORY_FILE structure to catch invalid usage. 118 // 119 memset (MemoryFile, 0xcc, sizeof (*MemoryFile)); 120 MemoryFile->Eof -= 1; 121 122 free (MemoryFile); 123 124 return EFI_SUCCESS; 125 } 126 127 128 CHAR8 * 129 ReadMemoryFileLine ( 130 IN EFI_HANDLE InputMemoryFile 131 ) 132 /*++ 133 134 Routine Description: 135 136 This function reads a line from the memory file. The newline characters 137 are stripped and a null terminated string is returned. 138 139 If the string pointer returned is non-NULL, then the caller must free the 140 memory associated with this string. 141 142 Arguments: 143 144 InputMemoryFile Handle to memory file 145 146 Returns: 147 148 NULL if error or EOF 149 NULL character termincated string otherwise (MUST BE FREED BY CALLER) 150 151 --*/ 152 { 153 CHAR8 *EndOfLine; 154 UINTN CharsToCopy; 155 MEMORY_FILE *InputFile; 156 UINTN BytesToEof; 157 CHAR8 *OutputString; 158 159 // 160 // Verify input parameters are not null 161 // 162 CheckMemoryFileState (InputMemoryFile); 163 164 InputFile = (MEMORY_FILE*)InputMemoryFile; 165 166 // 167 // Check for end of file condition 168 // 169 if (InputFile->CurrentFilePointer >= InputFile->Eof) { 170 return NULL; 171 } 172 173 // 174 // Determine the number of bytes remaining until the EOF 175 // 176 BytesToEof = InputFile->Eof - InputFile->CurrentFilePointer; 177 178 // 179 // Find the next newline char 180 // 181 EndOfLine = memchr (InputFile->CurrentFilePointer, '\n', BytesToEof); 182 183 // 184 // Determine the number of characters to copy. 185 // 186 if (EndOfLine == 0) { 187 // 188 // If no newline found, copy to the end of the file. 189 // 190 CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer; 191 } else { 192 // 193 // Newline found in the file. 194 // 195 CharsToCopy = EndOfLine - InputFile->CurrentFilePointer; 196 } 197 198 OutputString = malloc (CharsToCopy + 1); 199 if (OutputString == NULL) { 200 return NULL; 201 } 202 203 // 204 // Copy the line. 205 // 206 memcpy (OutputString, InputFile->CurrentFilePointer, CharsToCopy); 207 208 // 209 // Add the null termination over the 0x0D 210 // 211 if (OutputString[CharsToCopy - 1] == '\r') { 212 213 OutputString[CharsToCopy - 1] = '\0'; 214 215 } else { 216 217 OutputString[CharsToCopy] = '\0'; 218 219 } 220 221 // 222 // Increment the current file pointer (include the 0x0A) 223 // 224 InputFile->CurrentFilePointer += CharsToCopy + 1; 225 if (InputFile->CurrentFilePointer > InputFile->Eof) { 226 InputFile->CurrentFilePointer = InputFile->Eof; 227 } 228 CheckMemoryFileState (InputMemoryFile); 229 230 // 231 // Return the string 232 // 233 return OutputString; 234 } 235 236 237 STATIC 238 VOID 239 CheckMemoryFileState ( 240 IN EFI_HANDLE InputMemoryFile 241 ) 242 { 243 MEMORY_FILE *MemoryFile; 244 245 assert (InputMemoryFile != NULL); 246 247 MemoryFile = (MEMORY_FILE*)InputMemoryFile; 248 249 assert (MemoryFile->FileImage != NULL); 250 assert (MemoryFile->CurrentFilePointer != NULL); 251 assert (MemoryFile->Eof != NULL); 252 assert (MemoryFile->Eof >= MemoryFile->FileImage); 253 assert (MemoryFile->CurrentFilePointer >= MemoryFile->FileImage); 254 assert (MemoryFile->CurrentFilePointer <= MemoryFile->Eof); 255 } 256 257 258