/** @file Copyright (C) 2019, vit9696. All rights reserved. All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include #include #include #include #include #include #include #include #include #include "VirtualFsInternal.h" STATIC EFI_HANDLE_PROTOCOL mOriginalHandleProtocol; STATIC EFI_LOCATE_PROTOCOL mOriginalLocateProtocol; STATIC EFI_FILE_OPEN mOpenCallback; STATIC UINT32 mEntranceCount; STATIC VOID VirtualFsWrapProtocol ( IN EFI_GUID *Protocol, OUT VOID **Interface ) { EFI_STATUS Status; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; if (!CompareGuid (Protocol, &gEfiSimpleFileSystemProtocolGuid)) { return; } Status = CreateVirtualFs (*Interface, mOpenCallback, &FileSystem); if (!EFI_ERROR (Status)) { *Interface = FileSystem; } } STATIC EFI_STATUS EFIAPI VirtualFsHandleProtocol ( IN EFI_HANDLE Handle, IN EFI_GUID *Protocol, OUT VOID **Interface ) { EFI_STATUS Status; Status = mOriginalHandleProtocol (Handle, Protocol, Interface); if (!EFI_ERROR (Status) && (Interface != NULL) && (mEntranceCount == 0)) { ++mEntranceCount; VirtualFsWrapProtocol (Protocol, Interface); --mEntranceCount; } return Status; } STATIC EFI_STATUS EFIAPI VirtualFsLocateProtocol ( IN EFI_GUID *Protocol, IN VOID *Registration OPTIONAL, OUT VOID **Interface ) { EFI_STATUS Status; Status = mOriginalLocateProtocol (Protocol, Registration, Interface); if (!EFI_ERROR (Status) && (Interface != NULL) && (mEntranceCount == 0)) { ++mEntranceCount; VirtualFsWrapProtocol (Protocol, Interface); --mEntranceCount; } return Status; } EFI_STATUS EnableVirtualFs ( IN OUT EFI_BOOT_SERVICES *BootServices, IN EFI_FILE_OPEN OpenCallback ) { if ( (mOriginalHandleProtocol != NULL) || (BootServices->HandleProtocol == VirtualFsHandleProtocol)) { return EFI_ALREADY_STARTED; } // // Note, we should normally also hook OpenProtocol, but it results in freezes on APTIO IV and V. // mOpenCallback = OpenCallback; mOriginalHandleProtocol = BootServices->HandleProtocol; mOriginalLocateProtocol = BootServices->LocateProtocol; BootServices->HandleProtocol = VirtualFsHandleProtocol; BootServices->LocateProtocol = VirtualFsLocateProtocol; BootServices->Hdr.CRC32 = 0; BootServices->CalculateCrc32 (BootServices, BootServices->Hdr.HeaderSize, &BootServices->Hdr.CRC32); return EFI_SUCCESS; } EFI_STATUS DisableVirtualFs ( IN OUT EFI_BOOT_SERVICES *BootServices ) { if ( (mOriginalHandleProtocol == NULL) || (BootServices->HandleProtocol != VirtualFsHandleProtocol)) { return EFI_ALREADY_STARTED; } BootServices->HandleProtocol = mOriginalHandleProtocol; BootServices->LocateProtocol = mOriginalLocateProtocol; mOpenCallback = NULL; mOriginalHandleProtocol = NULL; mOriginalLocateProtocol = NULL; BootServices->Hdr.CRC32 = 0; BootServices->CalculateCrc32 (BootServices, BootServices->Hdr.HeaderSize, &BootServices->Hdr.CRC32); return EFI_SUCCESS; }