Home | History | Annotate | Download | only in FvbRuntimeService
      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