3 Copyright (c) 2006 - 2009, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 handles variable store/reads on file
23 #include "FSVariable.h"
25 VOID
*mSFSRegistration
;
33 OnVirtualAddressChangeFs (
41 IN VARIABLE_STORAGE
*This
47 IN VARIABLE_STORAGE
*This
,
55 IN EFI_DEVICE_PATH_PROTOCOL
*Device
,
56 IN CHAR16
*FilePathName
,
58 OUT EFI_FILE_PROTOCOL
**File
62 // Implementation below:
66 IN EFI_FILE_PROTOCOL
*File
71 Status
= File
->Flush (File
);
72 ASSERT_EFI_ERROR (Status
);
74 Status
= File
->Close (File
);
75 ASSERT_EFI_ERROR (Status
);
80 IN EFI_HANDLE SimpleFileSystemHandle
,
82 OUT EFI_DEVICE_PATH_PROTOCOL
**Device
85 #define BLOCK_SIZE 0x200
86 #define FAT16_VOLUME_ID_OFFSET 39
87 #define FAT32_VOLUME_ID_OFFSET 67
89 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
90 UINT8 BootSector
[BLOCK_SIZE
];
93 Status
= gBS
->HandleProtocol (
94 SimpleFileSystemHandle
,
95 &gEfiBlockIoProtocolGuid
, // BlockIo should be supported if it supports SimpleFileSystem
99 if (EFI_ERROR (Status
)) {
102 if (!BlkIo
->Media
->MediaPresent
) {
103 DEBUG ((EFI_D_ERROR
, "FileStorage: Media not present!\n"));
104 Status
= EFI_NO_MEDIA
;
107 if (BlkIo
->Media
->ReadOnly
) {
108 DEBUG ((EFI_D_ERROR
, "FileStorage: Media is read-only!\n"));
109 Status
= EFI_ACCESS_DENIED
;
113 Status
= BlkIo
->ReadBlocks(
115 BlkIo
->Media
->MediaId
,
120 ASSERT_EFI_ERROR (Status
);
121 if ((*(UINT32
*) &BootSector
[FAT16_VOLUME_ID_OFFSET
] != VolumeId
) &&
122 (*(UINT32
*) &BootSector
[FAT32_VOLUME_ID_OFFSET
] != VolumeId
)
124 Status
= EFI_NOT_FOUND
;
128 *Device
= DuplicateDevicePath (DevicePathFromHandle (SimpleFileSystemHandle
));
129 ASSERT (*Device
!= NULL
);
137 IN EFI_DEVICE_PATH_PROTOCOL
*Device
141 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Volume
;
144 Status
= gBS
->LocateDevicePath (
145 &gEfiSimpleFileSystemProtocolGuid
,
150 if (EFI_ERROR (Status
)) {
154 Status
= gBS
->HandleProtocol (
156 &gEfiSimpleFileSystemProtocolGuid
,
159 if (EFI_ERROR (Status
)) {
166 // this routine is still running in BS period, no limitation
167 // call FileInitStorage(), which load variable content file to memory
168 // read the store_header, init store_header if it has not been inited (read sth. about format/heathy)
169 // reclaim space using scratch memory
173 OnSimpleFileSystemInstall (
181 EFI_DEVICE_PATH_PROTOCOL
*Device
;
183 EFI_FILE_PROTOCOL
*File
;
186 Dev
= (VS_DEV
*) Context
;
188 if (VAR_FILE_DEVICEPATH (Dev
) != NULL
&&
189 !EFI_ERROR (CheckStoreExists (VAR_FILE_DEVICEPATH (Dev
)))
191 DEBUG ((EFI_D_ERROR
, "FileStorage: Already mapped!\n"));
196 HandleSize
= sizeof (EFI_HANDLE
);
197 Status
= gBS
->LocateHandle (
204 if (EFI_ERROR (Status
)) {
208 Status
= CheckStore (Handle
, VAR_FILE_VOLUMEID (Dev
), &Device
);
209 if (!EFI_ERROR (Status
)) {
214 VAR_FILE_DEVICEPATH (Dev
) = Device
;
216 VAR_FILE_DEVICEPATH (Dev
),
217 VAR_FILE_FILEPATH (Dev
),
218 EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
| EFI_FILE_MODE_CREATE
,
221 ASSERT_EFI_ERROR (Status
);
223 NumBytes
= Dev
->Size
;
224 Status
= File
->Write (File
, &NumBytes
, VAR_DATA_PTR (Dev
));
225 ASSERT_EFI_ERROR (Status
);
226 // KEN: bugbug here if closing file, volume handle will be free,
227 // and system will be hang when accessing volume handle in future.
229 DEBUG ((EFI_D_ERROR
, "FileStorage: Mapped to file!\n"));
233 FileStorageConstructor (
234 OUT VARIABLE_STORAGE
**VarStore
,
235 OUT EFI_EVENT_NOTIFY
*GoVirtualEvent
,
236 IN EFI_PHYSICAL_ADDRESS NvStorageBase
,
246 Status
= gBS
->AllocatePool (EfiRuntimeServicesData
, sizeof(VS_DEV
), (VOID
**) &Dev
);
247 ASSERT_EFI_ERROR (Status
);
248 ZeroMem (Dev
, sizeof(VS_DEV
));
250 Dev
->Signature
= VS_DEV_SIGNATURE
;
252 VAR_DATA_PTR (Dev
) = (UINT8
*) (UINTN
) NvStorageBase
;
253 VAR_FILE_VOLUMEID (Dev
) = VolumeId
;
254 StrCpy (VAR_FILE_FILEPATH (Dev
), FilePath
);
255 Dev
->VarStore
.Erase
= FileEraseStore
;
256 Dev
->VarStore
.Write
= FileWriteStore
;
258 DEBUG ((EFI_D_ERROR
, "FileStorageConstructor(0x%0x:0x%0x): added!\n", NvStorageBase
, Size
));
260 // add notify on SFS's installation.
262 Status
= gBS
->CreateEvent (
265 OnSimpleFileSystemInstall
,
269 ASSERT_EFI_ERROR (Status
);
271 Status
= gBS
->RegisterProtocolNotify (
272 &gEfiSimpleFileSystemProtocolGuid
,
276 ASSERT_EFI_ERROR (Status
);
278 *VarStore
= &Dev
->VarStore
;
279 *GoVirtualEvent
= OnVirtualAddressChangeFs
;
286 IN VARIABLE_STORAGE
*This
291 EFI_FILE_PROTOCOL
*File
;
294 Status
= EFI_SUCCESS
;
295 Dev
= DEV_FROM_THIS(This
);
297 SetMem (VAR_DATA_PTR (Dev
), Dev
->Size
, VAR_DEFAULT_VALUE
);
299 if (!EfiAtRuntime () && VAR_FILE_DEVICEPATH (Dev
) != NULL
) {
301 VAR_FILE_DEVICEPATH (Dev
),
302 VAR_FILE_FILEPATH (Dev
),
303 EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
,
306 ASSERT_EFI_ERROR (Status
);
307 NumBytes
= Dev
->Size
;
308 Status
= File
->Write (File
, &NumBytes
, VAR_DATA_PTR (Dev
));
309 ASSERT_EFI_ERROR (Status
);
319 IN VARIABLE_STORAGE
*This
,
327 EFI_FILE_PROTOCOL
*File
;
329 Status
= EFI_SUCCESS
;
330 Dev
= DEV_FROM_THIS(This
);
332 ASSERT (Buffer
!= NULL
);
333 ASSERT (Offset
+ BufferSize
<= Dev
->Size
);
335 CopyMem (VAR_DATA_PTR (Dev
) + Offset
, Buffer
, BufferSize
);
337 if (!EfiAtRuntime () && VAR_FILE_DEVICEPATH (Dev
) != NULL
) {
339 VAR_FILE_DEVICEPATH (Dev
),
340 VAR_FILE_FILEPATH (Dev
),
341 EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
,
344 Status
= File
->SetPosition (File
, Offset
);
345 ASSERT_EFI_ERROR (Status
);
346 Status
= File
->Write (File
, &BufferSize
, Buffer
);
347 ASSERT_EFI_ERROR (Status
);
355 OnVirtualAddressChangeFs (
362 Dev
= DEV_FROM_THIS (Context
);
364 EfiConvertPointer (0, (VOID
**) &VAR_DATA_PTR (Dev
));
365 EfiConvertPointer (0, (VOID
**) &Dev
->VarStore
.Erase
);
366 EfiConvertPointer (0, (VOID
**) &Dev
->VarStore
.Write
);
371 IN EFI_DEVICE_PATH_PROTOCOL
*Device
,
372 IN CHAR16
*FilePathName
,
374 OUT EFI_FILE_PROTOCOL
**File
378 EFI_FILE_HANDLE Root
;
379 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Volume
;
384 Status
= gBS
->LocateDevicePath (
385 &gEfiSimpleFileSystemProtocolGuid
,
390 if (EFI_ERROR (Status
)) {
394 Status
= gBS
->HandleProtocol (
396 &gEfiSimpleFileSystemProtocolGuid
,
399 if (EFI_ERROR (Status
)) {
404 // Open the root directory of the volume
407 Status
= Volume
->OpenVolume (
411 ASSERT_EFI_ERROR (Status
);
412 ASSERT (Root
!= NULL
);
417 Status
= Root
->Open (
424 if (EFI_ERROR (Status
)) {
429 // Close the Root directory