1 /**@file
2 Copyright (c) 2007 - 2009, Intel Corporation. All rights reserved.<BR>
3 This program and the accompanying materials
4 are licensed and made available under the terms and conditions of the BSD License
5 which accompanies this distribution. The full text of the license may be found at
6 http://opensource.org/licenses/bsd-license.php
7
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10
11 Module Name:
12
13 FileIo.c
14
15 Abstract:
16
17 File operation for Firmware volume block driver
18
19 **/
20 #include "FileIo.h"
21
22 //
23 // Variable storage hot plug is supported but there are still some restrictions:
24 // After plugging the storage back,
25 // 1. Still use memory as NV if newly plugged storage is not same as the original one
26 // 2. Still use memory as NV if there are some update operation during storage is unplugged.
27 //
28
29
30 EFI_STATUS
FileWrite(IN EFI_FILE_PROTOCOL * File,IN UINTN Offset,IN UINTN Buffer,IN UINTN Size)31 FileWrite (
32 IN EFI_FILE_PROTOCOL *File,
33 IN UINTN Offset,
34 IN UINTN Buffer,
35 IN UINTN Size
36 )
37 {
38 EFI_STATUS Status;
39
40 Status = File->SetPosition (File, Offset);
41 ASSERT_EFI_ERROR (Status);
42 if (!EFI_ERROR (Status)) {
43 Status = File->Write (File, &Size, (VOID *) Buffer);
44 ASSERT_EFI_ERROR (Status);
45 }
46 return Status;
47 }
48
49 EFI_STATUS
CheckStore(IN EFI_HANDLE SimpleFileSystemHandle,IN UINT32 VolumeId,OUT EFI_DEVICE_PATH_PROTOCOL ** Device)50 CheckStore (
51 IN EFI_HANDLE SimpleFileSystemHandle,
52 IN UINT32 VolumeId,
53 OUT EFI_DEVICE_PATH_PROTOCOL **Device
54 )
55 {
56 #define BLOCK_SIZE 0x200
57 #define FAT16_VOLUME_ID_OFFSET 39
58 #define FAT32_VOLUME_ID_OFFSET 67
59 EFI_STATUS Status;
60 EFI_BLOCK_IO_PROTOCOL *BlkIo;
61 UINT8 BootSector[BLOCK_SIZE];
62
63 *Device = NULL;
64 Status = gBS->HandleProtocol (
65 SimpleFileSystemHandle,
66 &gEfiBlockIoProtocolGuid, // BlockIo should be supported if it supports SimpleFileSystem
67 (VOID*)&BlkIo
68 );
69
70 if (EFI_ERROR (Status)) {
71 goto ErrHandle;
72 }
73 if (!BlkIo->Media->MediaPresent) {
74 DEBUG ((EFI_D_ERROR, "FwhMappedFile: Media not present!\n"));
75 Status = EFI_NO_MEDIA;
76 goto ErrHandle;
77 }
78 if (BlkIo->Media->ReadOnly) {
79 DEBUG ((EFI_D_ERROR, "FwhMappedFile: Media is read-only!\n"));
80 Status = EFI_ACCESS_DENIED;
81 goto ErrHandle;
82 }
83
84 Status = BlkIo->ReadBlocks(
85 BlkIo,
86 BlkIo->Media->MediaId,
87 0,
88 BLOCK_SIZE,
89 BootSector
90 );
91 ASSERT_EFI_ERROR (Status);
92 if ((*(UINT32 *) &BootSector[FAT16_VOLUME_ID_OFFSET] != VolumeId) &&
93 (*(UINT32 *) &BootSector[FAT32_VOLUME_ID_OFFSET] != VolumeId)
94 ) {
95 Status = EFI_NOT_FOUND;
96 goto ErrHandle;
97 }
98
99 *Device = DuplicateDevicePath (DevicePathFromHandle (SimpleFileSystemHandle));
100 ASSERT (*Device != NULL);
101
102 ErrHandle:
103 return Status;
104 }
105
106 EFI_STATUS
CheckStoreExists(IN EFI_DEVICE_PATH_PROTOCOL * Device)107 CheckStoreExists (
108 IN EFI_DEVICE_PATH_PROTOCOL *Device
109 )
110 {
111 EFI_HANDLE Handle;
112 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
113 EFI_STATUS Status;
114
115 Status = gBS->LocateDevicePath (
116 &gEfiSimpleFileSystemProtocolGuid,
117 &Device,
118 &Handle
119 );
120
121 if (EFI_ERROR (Status)) {
122 return Status;
123 }
124
125 Status = gBS->HandleProtocol (
126 Handle,
127 &gEfiSimpleFileSystemProtocolGuid,
128 &Volume
129 );
130 if (EFI_ERROR (Status)) {
131 return Status;
132 }
133
134 return EFI_SUCCESS;
135 }
136
137 VOID
FileClose(IN EFI_FILE_PROTOCOL * File)138 FileClose (
139 IN EFI_FILE_PROTOCOL *File
140 )
141 {
142 File->Flush (File);
143 File->Close (File);
144 }
145 EFI_STATUS
FileOpen(IN EFI_DEVICE_PATH_PROTOCOL * Device,IN CHAR16 * MappedFile,OUT EFI_FILE_PROTOCOL ** File,IN UINT64 OpenMode)146 FileOpen (
147 IN EFI_DEVICE_PATH_PROTOCOL *Device,
148 IN CHAR16 *MappedFile,
149 OUT EFI_FILE_PROTOCOL **File,
150 IN UINT64 OpenMode
151 )
152 {
153 EFI_HANDLE Handle;
154 EFI_FILE_HANDLE Root;
155 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
156 EFI_STATUS Status;
157
158 *File = NULL;
159
160 Status = gBS->LocateDevicePath (
161 &gEfiSimpleFileSystemProtocolGuid,
162 &Device,
163 &Handle
164 );
165
166 if (EFI_ERROR (Status)) {
167 return Status;
168 }
169
170 Status = gBS->HandleProtocol (
171 Handle,
172 &gEfiSimpleFileSystemProtocolGuid,
173 &Volume
174 );
175 ASSERT_EFI_ERROR (Status);
176 if (EFI_ERROR (Status)) {
177 return Status;
178 }
179
180 //
181 // Open the root directory of the volume
182 //
183 Root = NULL;
184 Status = Volume->OpenVolume (
185 Volume,
186 &Root
187 );
188 ASSERT_EFI_ERROR (Status);
189 ASSERT (Root != NULL);
190
191 //
192 // Open file
193 //
194 Status = Root->Open (
195 Root,
196 File,
197 MappedFile,
198 OpenMode,
199 0
200 );
201 if (EFI_ERROR (Status)) {
202 *File = NULL;
203 }
204
205 //
206 // Close the Root directory
207 //
208 Root->Close (Root);
209 return Status;
210 }
211