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
GetMemoryFile(IN CHAR8 * InputFileName,OUT EFI_HANDLE * OutputMemoryFile)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
FreeMemoryFile(IN EFI_HANDLE InputMemoryFile)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 *
ReadMemoryFileLine(IN EFI_HANDLE InputMemoryFile)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
CheckMemoryFileState(IN EFI_HANDLE InputMemoryFile)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