3 Copyright (c) 2006 - 2007, 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
;
34 OnVirtualAddressChange (
43 IN VARIABLE_STORAGE
*This
50 IN VARIABLE_STORAGE
*This
,
59 IN EFI_DEVICE_PATH_PROTOCOL
*Device
,
60 IN CHAR16
*FilePathName
,
66 // Implementation below:
76 Status
= File
->Flush (File
);
77 ASSERT_EFI_ERROR (Status
);
79 Status
= File
->Close (File
);
80 ASSERT_EFI_ERROR (Status
);
85 IN EFI_HANDLE SimpleFileSystemHandle
,
87 OUT EFI_DEVICE_PATH_PROTOCOL
**Device
90 #define BLOCK_SIZE 0x200
91 #define FAT16_VOLUME_ID_OFFSET 39
92 #define FAT32_VOLUME_ID_OFFSET 67
94 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
95 UINT8 BootSector
[BLOCK_SIZE
];
98 Status
= gBS
->HandleProtocol (
99 SimpleFileSystemHandle
,
100 &gEfiBlockIoProtocolGuid
, // BlockIo should be supported if it supports SimpleFileSystem
104 if (EFI_ERROR (Status
)) {
107 if (!BlkIo
->Media
->MediaPresent
) {
108 DEBUG ((EFI_D_ERROR
, "FileStorage: Media not present!\n"));
109 Status
= EFI_NO_MEDIA
;
112 if (BlkIo
->Media
->ReadOnly
) {
113 DEBUG ((EFI_D_ERROR
, "FileStorage: Media is read-only!\n"));
114 Status
= EFI_ACCESS_DENIED
;
118 Status
= BlkIo
->ReadBlocks(
120 BlkIo
->Media
->MediaId
,
125 ASSERT_EFI_ERROR (Status
);
126 if ((*(UINT32
*) &BootSector
[FAT16_VOLUME_ID_OFFSET
] != VolumeId
) &&
127 (*(UINT32
*) &BootSector
[FAT32_VOLUME_ID_OFFSET
] != VolumeId
)
129 Status
= EFI_NOT_FOUND
;
133 *Device
= DuplicateDevicePath (DevicePathFromHandle (SimpleFileSystemHandle
));
134 ASSERT (*Device
!= NULL
);
142 IN EFI_DEVICE_PATH_PROTOCOL
*Device
146 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Volume
;
149 Status
= gBS
->LocateDevicePath (
150 &gEfiSimpleFileSystemProtocolGuid
,
155 if (EFI_ERROR (Status
)) {
159 Status
= gBS
->HandleProtocol (
161 &gEfiSimpleFileSystemProtocolGuid
,
164 if (EFI_ERROR (Status
)) {
171 // this routine is still running in BS period, no limitation
172 // call FileInitStorage(), which load variable content file to memory
173 // read the store_header, init store_header if it has not been inited (read sth. about format/heathy)
174 // reclaim space using scratch memory
179 OnSimpleFileSystemInstall (
187 EFI_DEVICE_PATH_PROTOCOL
*Device
;
192 Dev
= (VS_DEV
*) Context
;
194 if (VAR_FILE_DEVICEPATH (Dev
) != NULL
&&
195 !EFI_ERROR (CheckStoreExists (VAR_FILE_DEVICEPATH (Dev
)))
197 DEBUG ((EFI_D_ERROR
, "FileStorage: Already mapped!\n"));
202 HandleSize
= sizeof (EFI_HANDLE
);
203 Status
= gBS
->LocateHandle (
210 if (EFI_ERROR (Status
)) {
214 Status
= CheckStore (Handle
, VAR_FILE_VOLUMEID (Dev
), &Device
);
215 if (!EFI_ERROR (Status
)) {
220 VAR_FILE_DEVICEPATH (Dev
) = Device
;
222 VAR_FILE_DEVICEPATH (Dev
),
223 VAR_FILE_FILEPATH (Dev
),
224 EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
| EFI_FILE_MODE_CREATE
,
227 ASSERT_EFI_ERROR (Status
);
229 NumBytes
= Dev
->Size
;
230 Status
= File
->Write (File
, &NumBytes
, VAR_DATA_PTR (Dev
));
231 ASSERT_EFI_ERROR (Status
);
233 DEBUG ((EFI_D_ERROR
, "FileStorage: Mapped to file!\n"));
237 FileStorageConstructor (
238 OUT VARIABLE_STORAGE
**VarStore
,
239 OUT EFI_EVENT_NOTIFY
*GoVirtualEvent
,
240 IN EFI_PHYSICAL_ADDRESS NvStorageBase
,
250 Status
= gBS
->AllocatePool (EfiRuntimeServicesData
, sizeof(VS_DEV
), &Dev
);
251 ASSERT_EFI_ERROR (Status
);
252 ZeroMem (Dev
, sizeof(VS_DEV
));
254 Dev
->Signature
= VARIABLE_STORE_SIGNATURE
;
256 VAR_DATA_PTR (Dev
) = (UINT8
*) (UINTN
) NvStorageBase
;
257 VAR_FILE_VOLUMEID (Dev
) = VolumeId
;
258 StrCpy (VAR_FILE_FILEPATH (Dev
), FilePath
);
259 Dev
->VarStore
.Erase
= FileEraseStore
;
260 Dev
->VarStore
.Write
= FileWriteStore
;
262 DEBUG ((EFI_D_ERROR
, "FileStorageConstructor(0x%0x:0x%0x): added!\n", NvStorageBase
, Size
));
264 // add notify on SFS's installation.
266 Status
= gBS
->CreateEvent (
267 EFI_EVENT_NOTIFY_SIGNAL
,
269 OnSimpleFileSystemInstall
,
273 ASSERT_EFI_ERROR (Status
);
275 Status
= gBS
->RegisterProtocolNotify (
276 &gEfiSimpleFileSystemProtocolGuid
,
280 ASSERT_EFI_ERROR (Status
);
282 *VarStore
= &Dev
->VarStore
;
283 *GoVirtualEvent
= OnVirtualAddressChange
;
291 IN VARIABLE_STORAGE
*This
299 Status
= EFI_SUCCESS
;
300 Dev
= DEV_FROM_THIS(This
);
302 SetMem (VAR_DATA_PTR (Dev
), Dev
->Size
, VAR_DEFAULT_VALUE
);
304 if (!EfiAtRuntime () && VAR_FILE_DEVICEPATH (Dev
) != NULL
) {
306 VAR_FILE_DEVICEPATH (Dev
),
307 VAR_FILE_FILEPATH (Dev
),
308 EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
,
311 ASSERT_EFI_ERROR (Status
);
312 NumBytes
= Dev
->Size
;
313 Status
= File
->Write (File
, &NumBytes
, VAR_DATA_PTR (Dev
));
314 ASSERT_EFI_ERROR (Status
);
325 IN VARIABLE_STORAGE
*This
,
335 Status
= EFI_SUCCESS
;
336 Dev
= DEV_FROM_THIS(This
);
338 ASSERT (Buffer
!= NULL
);
339 ASSERT (Offset
+ BufferSize
<= Dev
->Size
);
341 CopyMem (VAR_DATA_PTR (Dev
) + Offset
, Buffer
, BufferSize
);
343 if (!EfiAtRuntime () && VAR_FILE_DEVICEPATH (Dev
) != NULL
) {
345 VAR_FILE_DEVICEPATH (Dev
),
346 VAR_FILE_FILEPATH (Dev
),
347 EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
,
350 Status
= File
->SetPosition (File
, Offset
);
351 ASSERT_EFI_ERROR (Status
);
352 Status
= File
->Write (File
, &BufferSize
, Buffer
);
353 ASSERT_EFI_ERROR (Status
);
362 OnVirtualAddressChange (
369 Dev
= DEV_FROM_THIS (Context
);
371 EfiConvertPointer (0, &VAR_DATA_PTR (Dev
));
372 EfiConvertPointer (0, (VOID
**) &Dev
->VarStore
.Erase
);
373 EfiConvertPointer (0, (VOID
**) &Dev
->VarStore
.Write
);
379 IN EFI_DEVICE_PATH_PROTOCOL
*Device
,
380 IN CHAR16
*FilePathName
,
386 EFI_FILE_HANDLE Root
;
387 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Volume
;
392 Status
= gBS
->LocateDevicePath (
393 &gEfiSimpleFileSystemProtocolGuid
,
398 if (EFI_ERROR (Status
)) {
402 Status
= gBS
->HandleProtocol (
404 &gEfiSimpleFileSystemProtocolGuid
,
407 if (EFI_ERROR (Status
)) {
412 // Open the root directory of the volume
415 Status
= Volume
->OpenVolume (
419 ASSERT_EFI_ERROR (Status
);
420 ASSERT (Root
!= NULL
);
425 Status
= Root
->Open (
432 if (EFI_ERROR (Status
)) {
437 // Close the Root directory