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 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 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 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 138 FileClose ( 139 IN EFI_FILE_PROTOCOL *File 140 ) 141 { 142 File->Flush (File); 143 File->Close (File); 144 } 145 EFI_STATUS 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