Exemple #1
0
/**

  Function opens and returns a file handle to the root directory of a volume.

  @param DeviceHandle    A handle for a device

  @return A valid file handle or NULL is returned

**/
EFI_FILE_HANDLE
EfiLibOpenRoot (
  IN EFI_HANDLE                   DeviceHandle
  )
{
  EFI_STATUS                      Status;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
  EFI_FILE_HANDLE                 File;

  File = NULL;

  //
  // File the file system interface to the device
  //
  Status = refit_call3_wrapper(gBS->HandleProtocol,
                  DeviceHandle,
                  &gEfiSimpleFileSystemProtocolGuid,
                  (VOID **) &Volume
                  );

  //
  // Open the root directory of the volume
  //
  if (!EFI_ERROR (Status)) {
    Status = Volume->OpenVolume (
                      Volume,
                      &File
                      );
  }
  //
  // Done
  //
  return EFI_ERROR (Status) ? NULL : File;
}
Exemple #2
0
VOID EndlessIdleLoop(VOID)
{
    UINTN index;

    for (;;) {
        ReadAllKeyStrokes();
        refit_call3_wrapper(BS->WaitForEvent, 1, &ST->ConIn->WaitForKey, &index);
    }
}
Exemple #3
0
VOID egScreenShot(VOID)
{
    EFI_STATUS      Status;
    EG_IMAGE        *Image;
    UINT8           *FileData;
    UINTN           FileDataLength;
    UINTN           Index;
    
    if (!egHasGraphics)
        return;
    
    // allocate a buffer for the whole screen
    Image = egCreateImage(egScreenWidth, egScreenHeight, FALSE);
    if (Image == NULL) {
        Print(L"Error egCreateImage returned NULL\n");
        goto bailout_wait;
    }
    
    // get full screen image
    if (GraphicsOutput != NULL) {
        refit_call10_wrapper(GraphicsOutput->Blt, GraphicsOutput, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)Image->PixelData, EfiBltVideoToBltBuffer,
                            0, 0, 0, 0, Image->Width, Image->Height, 0);
    } else if (UgaDraw != NULL) {
        refit_call10_wrapper(UgaDraw->Blt, UgaDraw, (EFI_UGA_PIXEL *)Image->PixelData, EfiUgaVideoToBltBuffer,
                     0, 0, 0, 0, Image->Width, Image->Height, 0);
    }
    
    // encode as BMP
    egEncodeBMP(Image, &FileData, &FileDataLength);
    egFreeImage(Image);
    if (FileData == NULL) {
        Print(L"Error egEncodeBMP returned NULL\n");
        goto bailout_wait;
    }
    
    // save to file on the ESP
    Status = egSaveFile(NULL, L"screenshot.bmp", FileData, FileDataLength);
    FreePool(FileData);
    if (EFI_ERROR(Status)) {
        Print(L"Error egSaveFile: %x\n", Status);
        goto bailout_wait;
    }
    
    return;
    
    // DEBUG: switch to text mode
bailout_wait:
    egSetGraphicsModeEnabled(FALSE);
    refit_call3_wrapper(BS->WaitForEvent, 1, &ST->ConIn->WaitForKey, &Index);
}
Exemple #4
0
// The following is based on the grub_linuxefi_secure_validate() function in Fedora's
// version of GRUB 2.
// Returns TRUE if the specified data is validated by Shim's MOK, FALSE otherwise
BOOLEAN ShimValidate (VOID *data, UINT32 size)
{
   SHIM_LOCK   *shim_lock;
   EFI_GUID    ShimLockGuid = SHIM_LOCK_GUID;

   if ((data != NULL) && (refit_call3_wrapper(BS->LocateProtocol, &ShimLockGuid, NULL, (VOID**) &shim_lock) == EFI_SUCCESS)) {
      if (!shim_lock)
         return FALSE;

      if (shim_lock->shim_verify(data, size) == EFI_SUCCESS)
         return TRUE;
   }

   return FALSE;
} // BOOLEAN ShimValidate()
Exemple #5
0
static VOID DrawScreenHeader(IN CHAR16 *Title)
{
    UINTN y;

    // clear to black background
    egClearScreen(&DarkBackgroundPixel); // first clear in graphics mode
    refit_call2_wrapper(ST->ConOut->SetAttribute, ST->ConOut, ATTR_BASIC);
    refit_call1_wrapper(ST->ConOut->ClearScreen, ST->ConOut); // then clear in text mode

    // paint header background
    refit_call2_wrapper(ST->ConOut->SetAttribute, ST->ConOut, ATTR_BANNER);
    for (y = 0; y < 3; y++) {
        refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, 0, y);
        Print(BlankLine);
    }

    // print header text
    refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, 3, 1);
    Print(L"rEFInd - %s", Title);

    // reposition cursor
    refit_call2_wrapper(ST->ConOut->SetAttribute, ST->ConOut, ATTR_BASIC);
    refit_call3_wrapper(ST->ConOut->SetCursorPosition, ST->ConOut, 0, 4);
}
Exemple #6
0
/**

  Find the first instance of this Protocol
  in the system and return it's interface.


  @param ProtocolGuid    Provides the protocol to search for
  @param Interface       On return, a pointer to the first interface
                         that matches ProtocolGuid

  @retval  EFI_SUCCESS      A protocol instance matching ProtocolGuid was found
  @retval  EFI_NOT_FOUND    No protocol instances were found that match ProtocolGuid

**/
EFI_STATUS
EfiLibLocateProtocol (
  IN  EFI_GUID    *ProtocolGuid,
  OUT VOID        **Interface
  )
{
  EFI_STATUS  Status;

  Status = refit_call3_wrapper(gBS->LocateProtocol,
                  ProtocolGuid,
                  NULL,
                  (VOID **) Interface
                  );
  return Status;
}
Exemple #7
0
static int scan_disks(int (*hook)(struct fsw_volume *, struct fsw_volume *), struct fsw_volume *master)
{
    EFI_STATUS  Status;
    EFI_HANDLE *Handles;
    UINTN       HandleCount = 0;
    UINTN       i;
    UINTN       scanned = 0;

    // Driver hangs if compiled with GNU-EFI unless there's a Print() statement somewhere.
    // I'm still trying to track that down; in the meantime, work around it....
#if defined(__MAKEWITH_GNUEFI)
    Print(L" ");
#endif
    DPRINT(L"Scanning disks\n");
    Status = refit_call5_wrapper(BS->LocateHandleBuffer, ByProtocol, &gEfiDiskIoProtocolGuid, NULL, &HandleCount, &Handles);
    if (Status == EFI_NOT_FOUND)
        return -1;  // no filesystems. strange, but true...
    for (i = 0; i < HandleCount; i++) {
        EFI_DISK_IO *diskio;
        EFI_BLOCK_IO *blockio;
        Status = refit_call3_wrapper(BS->HandleProtocol, Handles[i], &gEfiDiskIoProtocolGuid, (VOID **) &diskio);
        if (Status != 0)
            continue;
        Status = refit_call3_wrapper(BS->HandleProtocol, Handles[i], &gEfiBlockIoProtocolGuid, (VOID **) &blockio);
        if (Status != 0)
            continue;
        struct fsw_volume *vol = create_dummy_volume(diskio, blockio->Media->MediaId);
        if(vol) {
            DPRINT(L"Checking disk %d\n", i);
            if(hook(master, vol) == FSW_SUCCESS)
                scanned++;
            free_dummy_volume(vol);
        }
    }
    return scanned;
}
Exemple #8
0
VOID PauseForKey(VOID)
{
    UINTN index;

    Print(L"\n* Hit any key to continue *");

    if (ReadAllKeyStrokes()) {  // remove buffered key strokes
        refit_call1_wrapper(BS->Stall, 5000000);     // 5 seconds delay
        ReadAllKeyStrokes();    // empty the buffer again
    }

    refit_call3_wrapper(BS->WaitForEvent, 1, &ST->ConIn->WaitForKey, &index);
    ReadAllKeyStrokes();        // empty the buffer to protect the menu

    Print(L"\n");
}
Exemple #9
0
/**
    Boot the legacy system with the boot option

    @param  Option                 The legacy boot option which have BBS device path

    @retval EFI_UNSUPPORTED        There is no legacybios protocol, do not support
                                 legacy boot.
    @retval EFI_STATUS             Return the status of LegacyBios->LegacyBoot ().

**/
EFI_STATUS
BdsLibDoLegacyBoot (
  IN  BDS_COMMON_OPTION           *Option
  )
{
    EFI_STATUS                Status;
    EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;

    Status = refit_call3_wrapper(gBS->LocateProtocol, &gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios);
    if (EFI_ERROR (Status)) {
      return EFI_UNSUPPORTED;
    }

    UpdateBbsTable(Option);

    return refit_call4_wrapper(LegacyBios->LegacyBoot, LegacyBios, (BBS_BBS_DEVICE_PATH *) Option->DevicePath,
                                  Option->LoadOptionsSize, Option->LoadOptions);
}
Exemple #10
0
EFI_STATUS egLoadFile(IN EFI_FILE* BaseDir, IN CHAR16 *FileName, OUT UINT8 **FileData, OUT UINTN *FileDataLength)
{
    EFI_STATUS          Status;
    EFI_FILE_HANDLE     FileHandle;
    EFI_FILE_INFO       *FileInfo;
    UINT64              ReadSize;
    UINTN               BufferSize;
    UINT8               *Buffer;

    Status = refit_call5_wrapper(BaseDir->Open, BaseDir, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
    if (EFI_ERROR(Status)) {
        return Status;
    }

    FileInfo = LibFileInfo(FileHandle);
    if (FileInfo == NULL) {
        refit_call1_wrapper(FileHandle->Close, FileHandle);
        return EFI_NOT_FOUND;
    }
    ReadSize = FileInfo->FileSize;
    if (ReadSize > MAX_FILE_SIZE)
        ReadSize = MAX_FILE_SIZE;
    FreePool(FileInfo);

    BufferSize = (UINTN)ReadSize;   // was limited to 1 GB above, so this is safe
    Buffer = (UINT8 *) AllocatePool(BufferSize);
    if (Buffer == NULL) {
        refit_call1_wrapper(FileHandle->Close, FileHandle);
        return EFI_OUT_OF_RESOURCES;
    }

    Status = refit_call3_wrapper(FileHandle->Read, FileHandle, &BufferSize, Buffer);
    refit_call1_wrapper(FileHandle->Close, FileHandle);
    if (EFI_ERROR(Status)) {
        FreePool(Buffer);
        return Status;
    }

    *FileData = Buffer;
    *FileDataLength = BufferSize;
    return EFI_SUCCESS;
}
Exemple #11
0
// Function to tell the firmware that OS X is being launched. This is
// required to work around problems on some Macs that don't fully
// initialize some hardware (especially video displays) when third-party
// OSes are launched in EFI mode.
EFI_STATUS SetAppleOSInfo() {
    CHAR16 *AppleOSVersion = NULL;
    CHAR8 *AppleOSVersion8 = NULL;
    EFI_STATUS Status;
    EFI_GUID apple_set_os_guid = EFI_APPLE_SET_OS_PROTOCOL_GUID;
    EfiAppleSetOsInterface *SetOs = NULL;

    Status = refit_call3_wrapper(BS->LocateProtocol, &apple_set_os_guid, NULL, (VOID**) &SetOs);

    // If not a Mac, ignore the call....
    if ((Status != EFI_SUCCESS) || (!SetOs))
        return EFI_SUCCESS;

    if ((SetOs->Version != 0) && GlobalConfig.SpoofOSXVersion) {
        AppleOSVersion = StrDuplicate(L"Mac OS X");
        MergeStrings(&AppleOSVersion, GlobalConfig.SpoofOSXVersion, ' ');
        if (AppleOSVersion) {
            AppleOSVersion8 = AllocateZeroPool((StrLen(AppleOSVersion) + 1) * sizeof(CHAR8));
            UnicodeStrToAsciiStr(AppleOSVersion, AppleOSVersion8);
            if (AppleOSVersion8) {
                Status = refit_call1_wrapper (SetOs->SetOsVersion, AppleOSVersion8);
                if (!EFI_ERROR(Status))
                    Status = EFI_SUCCESS;
                MyFreePool(AppleOSVersion8);
            } else {
                Status = EFI_OUT_OF_RESOURCES;
                Print(L"Out of resources in SetAppleOSInfo!\n");
            }
            if ((Status == EFI_SUCCESS) && (SetOs->Version == 2))
                Status = refit_call1_wrapper (SetOs->SetOsVendor, (CHAR8 *) "Apple Inc.");
            MyFreePool(AppleOSVersion);
        } // if (AppleOSVersion)
    } // if
    if (Status != EFI_SUCCESS)
        Print(L"Unable to set firmware boot type!\n");

    return (Status);
} // EFI_STATUS SetAppleOSInfo()
Exemple #12
0
// Returns TRUE if the shim program is available to verify binaries,
// FALSE if not
BOOLEAN ShimLoaded(void) {
   SHIM_LOCK   *shim_lock;
   EFI_GUID    ShimLockGuid = SHIM_LOCK_GUID;

   return (refit_call3_wrapper(BS->LocateProtocol, &ShimLockGuid, NULL, (VOID**) &shim_lock) == EFI_SUCCESS);
} // ShimLoaded()
Exemple #13
0
/**
    Internal helper function.

    Update the BBS Table so that devices of DeviceType have their boot priority
    updated to a high/bootable value.

    See "DeviceType values" in 
    http://www.intel.com/content/dam/doc/reference-guide/efi-compatibility-support-module-specification-v097.pdf

    NOTE: This function should probably be refactored! Currently, all devices of
    type are enabled. This should be updated so that only a specific device is
    enabled. The wrong device could boot if there are multiple targets of the same
    type.

    @param DeviceType   The device type that we wish to enable
**/
VOID UpdateBbsTable (BDS_COMMON_OPTION *Option) {
   UINT16  Idx;
   EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
   EFI_STATUS                Status;
   UINT16                       HddCount = 0;
   HDD_INFO                     *HddInfo = NULL; 
   UINT16                       BbsCount = 0; 
   BBS_TABLE                 *LocalBbsTable = NULL;
   BBS_BBS_DEVICE_PATH       *OptionBBS;
   CHAR16                    Desc[100];

   Status = refit_call3_wrapper(gBS->LocateProtocol, &gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios);
   if (EFI_ERROR (Status) || (Option == NULL)) {
      return;
   }

   OptionBBS = (BBS_BBS_DEVICE_PATH *) Option->DevicePath;
   Status = refit_call5_wrapper(LegacyBios->GetBbsInfo, LegacyBios, &HddCount, &HddInfo, &BbsCount, &LocalBbsTable);

//    Print (L"\n");
//    Print (L" NO  Prio bb/dd/ff cl/sc Type Stat segm:offs\n");
//    Print (L"=============================================\n");

   for (Idx = 0; Idx < BbsCount; Idx++) {
      if(LocalBbsTable[Idx].DeviceType == 0) {
         continue;
      }

      BdsBuildLegacyDevNameString (&LocalBbsTable[Idx], Idx, sizeof (Desc), Desc);

      // Set devices of a particular type to BootPriority of 0 or 1. 0 is the highest priority.
      if (LocalBbsTable[Idx].DeviceType == OptionBBS->DeviceType) {
         if (StriCmp(Desc, Option->Description) == 0) {
            // This entry exactly matches what we're looking for; make it highest priority
            LocalBbsTable[Idx].BootPriority = 0;
         } else {
            // This entry doesn't exactly match, but is the right disk type; make it a bit lower
            // in priority. Done mainly as a fallback in case of string-matching weirdness.
            LocalBbsTable[Idx].BootPriority = 1;
         } // if/else
      } else if (LocalBbsTable[Idx].BootPriority <= 1) {
         // Something's got a high enough boot priority to interfere with booting
         // our chosen entry, so bump it down a bit....
         LocalBbsTable[Idx].BootPriority = 2;
      } // if/else if

//          Print (
//            L" %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n",
//            (UINTN) Idx,
//            (UINTN) LocalBbsTable[Idx].BootPriority,
//            (UINTN) LocalBbsTable[Idx].Bus,
//            (UINTN) LocalBbsTable[Idx].Device,
//            (UINTN) LocalBbsTable[Idx].Function,
//            (UINTN) LocalBbsTable[Idx].Class,
//            (UINTN) LocalBbsTable[Idx].SubClass,
//            (UINTN) LocalBbsTable[Idx].DeviceType,
//            (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags,
//            (UINTN) LocalBbsTable[Idx].BootHandlerSegment,
//            (UINTN) LocalBbsTable[Idx].BootHandlerOffset,
//            (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset),
//            (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset)
//            );
//          Print(L"%s\n", Desc);

   } // for
//    PauseForKey();
}