1 /** @file 2 This contains some useful functions for accessing files. 3 4 Copyright (c) 2004 - 2014, 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 return EFI_OUT_OF_RESOURCES; 73 } 74 75 NewMemoryFile->FileImage = InputFileImage; 76 NewMemoryFile->CurrentFilePointer = InputFileImage; 77 NewMemoryFile->Eof = InputFileImage + BytesRead; 78 79 *OutputMemoryFile = (EFI_HANDLE)NewMemoryFile; 80 81 CheckMemoryFileState (*OutputMemoryFile); 82 83 return EFI_SUCCESS; 84 } 85 86 87 EFI_STATUS 88 FreeMemoryFile ( 89 IN EFI_HANDLE InputMemoryFile 90 ) 91 /*++ 92 93 Routine Description: 94 95 Frees all memory associated with the input memory file. 96 97 Arguments: 98 99 InputMemoryFile Handle to memory file 100 101 Returns: 102 103 EFI_STATUS 104 105 --*/ 106 { 107 MEMORY_FILE *MemoryFile; 108 109 CheckMemoryFileState (InputMemoryFile); 110 111 MemoryFile = (MEMORY_FILE*)InputMemoryFile; 112 113 free (MemoryFile->FileImage); 114 115 // 116 // Invalidate state of MEMORY_FILE structure to catch invalid usage. 117 // 118 memset (MemoryFile, 0xcc, sizeof (*MemoryFile)); 119 MemoryFile->Eof -= 1; 120 121 free (MemoryFile); 122 123 return EFI_SUCCESS; 124 } 125 126 127 CHAR8 * 128 ReadMemoryFileLine ( 129 IN EFI_HANDLE InputMemoryFile 130 ) 131 /*++ 132 133 Routine Description: 134 135 This function reads a line from the memory file. The newline characters 136 are stripped and a null terminated string is returned. 137 138 If the string pointer returned is non-NULL, then the caller must free the 139 memory associated with this string. 140 141 Arguments: 142 143 InputMemoryFile Handle to memory file 144 145 Returns: 146 147 NULL if error or EOF 148 NULL character termincated string otherwise (MUST BE FREED BY CALLER) 149 150 --*/ 151 { 152 CHAR8 *EndOfLine; 153 UINTN CharsToCopy; 154 MEMORY_FILE *InputFile; 155 UINTN BytesToEof; 156 CHAR8 *OutputString; 157 158 // 159 // Verify input parameters are not null 160 // 161 CheckMemoryFileState (InputMemoryFile); 162 163 InputFile = (MEMORY_FILE*)InputMemoryFile; 164 165 // 166 // Check for end of file condition 167 // 168 if (InputFile->CurrentFilePointer >= InputFile->Eof) { 169 return NULL; 170 } 171 172 // 173 // Determine the number of bytes remaining until the EOF 174 // 175 BytesToEof = InputFile->Eof - InputFile->CurrentFilePointer; 176 177 // 178 // Find the next newline char 179 // 180 EndOfLine = memchr (InputFile->CurrentFilePointer, '\n', BytesToEof); 181 182 // 183 // Determine the number of characters to copy. 184 // 185 if (EndOfLine == 0) { 186 // 187 // If no newline found, copy to the end of the file. 188 // 189 CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer; 190 } else { 191 // 192 // Newline found in the file. 193 // 194 CharsToCopy = EndOfLine - InputFile->CurrentFilePointer; 195 } 196 197 OutputString = malloc (CharsToCopy + 1); 198 if (OutputString == NULL) { 199 return NULL; 200 } 201 202 // 203 // Copy the line. 204 // 205 memcpy (OutputString, InputFile->CurrentFilePointer, CharsToCopy); 206 207 // 208 // Add the null termination over the 0x0D 209 // 210 if (OutputString[CharsToCopy - 1] == '\r') { 211 212 OutputString[CharsToCopy - 1] = '\0'; 213 214 } else { 215 216 OutputString[CharsToCopy] = '\0'; 217 218 } 219 220 // 221 // Increment the current file pointer (include the 0x0A) 222 // 223 InputFile->CurrentFilePointer += CharsToCopy + 1; 224 CheckMemoryFileState (InputMemoryFile); 225 226 // 227 // Return the string 228 // 229 return OutputString; 230 } 231 232 233 STATIC 234 VOID 235 CheckMemoryFileState ( 236 IN EFI_HANDLE InputMemoryFile 237 ) 238 { 239 MEMORY_FILE *MemoryFile; 240 241 assert (InputMemoryFile != NULL); 242 243 MemoryFile = (MEMORY_FILE*)InputMemoryFile; 244 245 assert (MemoryFile->FileImage != NULL); 246 assert (MemoryFile->CurrentFilePointer != NULL); 247 assert (MemoryFile->Eof != NULL); 248 assert (MemoryFile->Eof >= MemoryFile->FileImage); 249 assert (MemoryFile->CurrentFilePointer >= MemoryFile->FileImage); 250 assert (MemoryFile->CurrentFilePointer <= MemoryFile->Eof); 251 } 252 253 254