1 /** @file
2   Library functions that perform file IO. Memory buffer, file system, and
3   fimrware volume operations are supproted.
4 
5   Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
6   Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
7 
8   This program and the accompanying materials
9   are licensed and made available under the terms and conditions of the BSD License
10   which accompanies this distribution.  The full text of the license may be found at
11   http://opensource.org/licenses/bsd-license.php
12 
13   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 
16   Basic support for opening files on different device types. The device string
17   is in the form of DevType:Path. Current DevType is required as there is no
18   current mounted device concept of current working directory concept implement
19   by this library.
20 
21   Device names are case insensative and only check the leading characters for
22   unique matches. Thus the following are all the same:
23     LoadFile0:
24     l0:
25     L0:
26     Lo0:
27 
28   Supported Device Names:
29   A0x1234:0x12 - A memory buffer starting at address 0x1234 for 0x12 bytes
30   l1:          - EFI LoadFile device one.
31   B0:          - EFI BlockIo zero.
32   fs3:         - EFI Simple File System device 3
33   Fv2:         - EFI Firmware VOlume device 2
34   1.2.3.4:name - TFTP IP and file name
35 
36 **/
37 
38 #ifndef __EFI_FILE_LIB_H__
39 #define __EFI_FILE_LIB_H__
40 
41 #include <PiDxe.h>
42 #include <Protocol/FirmwareVolume2.h>
43 #include <Protocol/FirmwareVolumeBlock.h>
44 #include <Protocol/BlockIo.h>
45 #include <Protocol/LoadFile.h>
46 #include <Protocol/LoadFile.h>
47 #include <Protocol/SimpleFileSystem.h>
48 #include <Guid/FileInfo.h>
49 #include <Guid/FileSystemInfo.h>
50 
51 #define MAX_PATHNAME    0x200
52 
53 /// Type of the file that has been opened
54 typedef enum {
55   EfiOpenLoadFile,
56   EfiOpenMemoryBuffer,
57   EfiOpenFirmwareVolume,
58   EfiOpenFileSystem,
59   EfiOpenBlockIo,
60   EfiOpenTftp,
61   EfiOpenMaxValue
62 } EFI_OPEN_FILE_TYPE;
63 
64 
65 /// Public information about the open file
66 typedef struct {
67   UINTN                         Version;          // Common information
68   EFI_OPEN_FILE_TYPE            Type;
69   EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
70   EFI_STATUS                    LastError;
71   EFI_HANDLE                    EfiHandle;
72   CHAR8                         *DeviceName;
73   CHAR8                         *FileName;
74 
75   UINT64                        CurrentPosition;  // Information for Seek
76   UINT64                        MaxPosition;
77 
78   UINTN                         BaseOffset;       // Base offset for hexdump command
79 
80   UINTN                         Size;             // Valid for all types other than l#:
81   UINT8                         *Buffer;          // Information valid for A#:
82 
83   EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;              // Information valid for Fv#:
84   EFI_GUID                      FvNameGuid;
85   EFI_SECTION_TYPE              FvSectionType;
86   EFI_FV_FILETYPE               FvType;
87   EFI_FV_FILE_ATTRIBUTES        FvAttributes;
88 
89   EFI_PHYSICAL_ADDRESS          FvStart;
90   UINTN                         FvSize;
91   UINTN                         FvHeaderSize;
92 
93   EFI_FILE                      *FsFileHandle;    // Information valid for Fs#:
94   EFI_FILE_SYSTEM_INFO          *FsInfo;
95   EFI_FILE_INFO                 *FsFileInfo;
96   EFI_BLOCK_IO_MEDIA            *FsBlockIoMedia;  // Information valid for Fs#: or B#:
97   EFI_BLOCK_IO_PROTOCOL         *FsBlockIo;       // Information valid for Fs#: or B#:
98 
99   UINTN                         DiskOffset;       // Information valid for B#:
100 
101   EFI_LOAD_FILE_PROTOCOL        *LoadFile;        // Information valid for l#:
102 
103   EFI_IP_ADDRESS                ServerIp;         // Information valid for t:
104   BOOLEAN                       IsDirty;
105   BOOLEAN                       IsBufferValid;
106 
107 } EFI_OPEN_FILE;
108 
109 
110 /// Type of Seek to perform
111 typedef enum {
112   EfiSeekStart,
113   EfiSeekCurrent,
114   EfiSeekEnd,
115   EfiSeekMax
116 } EFI_SEEK_TYPE;
117 
118 
119 /**
120   Open a device named by PathName. The PathName includes a device name and
121   path separated by a :. See file header for more details on the PathName
122   syntax. There is no checking to prevent a file from being opened more than
123   one type.
124 
125   SectionType is only used to open an FV. Each file in an FV contains multiple
126   sections and only the SectionType section is opened.
127 
128   For any file that is opened with EfiOpen() must be closed with EfiClose().
129 
130   @param  PathName    Path to parse to open
131   @param  OpenMode    Same as EFI_FILE.Open()
132   @param  SectionType Section in FV to open.
133 
134   @return NULL  Open failed
135   @return Valid EFI_OPEN_FILE handle
136 
137 **/
138 EFI_OPEN_FILE *
139 EfiOpen (
140   IN        CHAR8               *PathName,
141   IN  CONST UINT64              OpenMode,
142   IN  CONST EFI_SECTION_TYPE    SectionType
143   );
144 
145 EFI_STATUS
146 EfiCopyFile (
147   IN        CHAR8               *DestinationFile,
148   IN        CHAR8               *SourceFile
149   );
150 
151 /**
152   Use DeviceType and Index to form a valid PathName and try and open it.
153 
154   @param  DeviceType  Device type to open
155   @param  Index       Device Index to use. Zero relative.
156 
157   @return NULL  Open failed
158   @return Valid EFI_OPEN_FILE handle
159 
160 **/
161 EFI_OPEN_FILE  *
162 EfiDeviceOpenByType (
163   IN  EFI_OPEN_FILE_TYPE    DeviceType,
164   IN  UINTN                 Index
165   );
166 
167 
168 /**
169   Close a file handle opened by EfiOpen() and free all resources allocated by
170   EfiOpen().
171 
172   @param  Stream    Open File Handle
173 
174   @return EFI_INVALID_PARAMETER  Stream is not an Open File
175   @return EFI_SUCCESS            Steam closed
176 
177 **/
178 EFI_STATUS
179 EfiClose (
180   IN  EFI_OPEN_FILE     *Stream
181   );
182 
183 
184 /**
185   Return the size of the file represented by Stream. Also return the current
186   Seek position. Opening a file will enable a valid file size to be returned.
187   LoadFile is an exception as a load file size is set to zero.
188 
189   @param  Stream    Open File Handle
190 
191   @return 0         Stream is not an Open File or a valid LoadFile handle
192 
193 **/
194 UINTN
195 EfiTell (
196   IN  EFI_OPEN_FILE     *Stream,
197   OUT UINT64            *CurrentPosition   OPTIONAL
198   );
199 
200 
201 /**
202   Seek to the Offset location in the file. LoadFile and FV device types do
203   not support EfiSeek(). It is not possible to grow the file size using
204   EfiSeek().
205 
206   SeekType defines how use Offset to calculate the new file position:
207   EfiSeekStart  : Position = Offset
208   EfiSeekCurrent: Position is Offset bytes from the current position
209   EfiSeekEnd    : Only supported if Offset is zero to seek to end of file.
210 
211   @param  Stream    Open File Handle
212   @param  Offset    Offset to seek too.
213   @param  SeekType  Type of seek to perform
214 
215 
216   @return EFI_INVALID_PARAMETER  Stream is not an Open File
217   @return EFI_UNSUPPORTED        LoadFile and FV does not support Seek
218   @return EFI_NOT_FOUND          Seek past the end of the file.
219   @return EFI_SUCCESS            Steam closed
220 
221 **/
222 EFI_STATUS
223 EfiSeek (
224   IN  EFI_OPEN_FILE     *Stream,
225   IN  EFI_LBA           Offset,
226   IN  EFI_SEEK_TYPE     SeekType
227   );
228 
229 
230 /**
231   Read BufferSize bytes from the current location in the file. For load file
232   and FV case you must read the entire file.
233 
234   @param  Stream      Open File Handle
235   @param  Buffer      Caller allocated buffer.
236   @param  BufferSize  Size of buffer in bytes.
237 
238 
239   @return EFI_SUCCESS           Stream is not an Open File
240   @return EFI_END_OF_FILE Tried to read past the end of the file
241   @return EFI_INVALID_PARAMETER Stream is not an open file handle
242   @return EFI_BUFFER_TOO_SMALL  Buffer is not big enough to do the read
243   @return "other"               Error returned from device read
244 
245 **/
246 EFI_STATUS
247 EfiRead (
248   IN  EFI_OPEN_FILE     *Stream,
249   OUT VOID              *Buffer,
250   OUT UINTN             *BufferSize
251   );
252 
253 
254 /**
255   Read the entire file into a buffer. This routine allocates the buffer and
256   returns it to the user full of the read data.
257 
258   This is very useful for load file where it's hard to know how big the buffer
259   must be.
260 
261   @param  Stream      Open File Handle
262   @param  Buffer      Pointer to buffer to return.
263   @param  BufferSize  Pointer to Size of buffer return..
264 
265 
266   @return EFI_SUCCESS           Stream is not an Open File
267   @return EFI_END_OF_FILE       Tried to read past the end of the file
268   @return EFI_INVALID_PARAMETER Stream is not an open file handle
269   @return EFI_BUFFER_TOO_SMALL  Buffer is not big enough to do the read
270   @return "other"               Error returned from device read
271 
272 **/
273 EFI_STATUS
274 EfiReadAllocatePool (
275   IN  EFI_OPEN_FILE     *Stream,
276   OUT VOID              **Buffer,
277   OUT UINTN             *BufferSize
278   );
279 
280 
281 /**
282   Write data back to the file.
283 
284   @param  Stream      Open File Handle
285   @param  Buffer      Pointer to buffer to return.
286   @param  BufferSize  Pointer to Size of buffer return..
287 
288 
289   @return EFI_SUCCESS           Stream is not an Open File
290   @return EFI_END_OF_FILE       Tried to read past the end of the file
291   @return EFI_INVALID_PARAMETER Stream is not an open file handle
292   @return EFI_BUFFER_TOO_SMALL  Buffer is not big enough to do the read
293   @return "other"               Error returned from device write
294 
295 **/
296 EFI_STATUS
297 EfiWrite (
298   IN  EFI_OPEN_FILE   *Stream,
299   OUT VOID            *Buffer,
300   OUT UINTN           *BufferSize
301   );
302 
303 
304 /**
305   Return the number of devices of the current type active in the system
306 
307   @param  Type      Device type to check
308 
309   @return 0         Invalid type
310 
311 **/
312 UINTN
313 EfiGetDeviceCounts (
314   IN  EFI_OPEN_FILE_TYPE     Type
315   );
316 
317 
318 /**
319   Set the Current Working Directory (CWD). If a call is made to EfiOpen () and
320   the path does not contain a device name, The CWD is prepended to the path.
321 
322   @param  Cwd     Current Working Directory to set
323 
324 
325   @return EFI_SUCCESS           CWD is set
326   @return EFI_INVALID_PARAMETER Cwd is not a valid device:path
327 
328 **/
329 EFI_STATUS
330 EfiSetCwd (
331   IN  CHAR8   *Cwd
332   );
333 
334 /**
335   Set the Current Working Directory (CWD). If a call is made to EfiOpen () and
336   the path does not contain a device name, The CWD is prepended to the path.
337 
338   @param  Cwd     Current Working Directory
339 
340 
341   @return NULL    No CWD set
342   @return 'other' malloc'ed buffer contains CWD.
343 
344 **/
345 CHAR8 *
346 EfiGetCwd (
347   VOID
348   );
349 
350 #endif
351