dumpbs.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,125 行 · 第 1/2 页

C
1,125
字号
  Status = FileHandle->SetPosition (FileHandle, 0);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: Set %hs pos error - %r\n", FileName, Status);
    goto Done;
  }

  //
  // Read data from file
  //
  Status = FileHandle->Read (FileHandle, &BufSize, Buffer);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: - Read error - %r\n", Status);
    goto Done;
  }

  //
  // Whether Boot sector file size is 512
  //
  if (BufSize != BOOT_HEADER_SIZE) {
    Print(L"dumpbs: Error, Boot sector file is smaller than %d bytes\n", BOOT_HEADER_SIZE);
    Status = EFI_ABORTED;
    goto Done;
  }

  //
  // Read block device's boot sector to TempBuffer
  //      
  Status = BlkIo->ReadBlocks (BlkIo, BlkIo->Media->MediaId, 0, BOOT_HEADER_SIZE, TempBuffer);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: Read boot sector error - %r\n", Status);
    goto Done;
  }

  //
  // Update target buffer
  //
  PatchBlock (Buffer, TempBuffer, TRUE);

  //
  // Finnally write the boot sector
  //
  Status = BlkIo->WriteBlocks (BlkIo, BlkIo->Media->MediaId, 0, BOOT_HEADER_SIZE, Buffer);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: Write boot sector error - %r\n", Status);
    goto Done;
  }

  Print(L"dumpbs: Write boot sector finished\n");

Done:
  FreePool(TempBuffer);
  FreePool(Buffer);
  FileHandle->Close(FileHandle);

  return Status;
}

EFI_STATUS
WriteBootSector (
  IN CHAR16       *BlkIoName,
  IN CHAR16       *FileName,
  IN UINT64       StartingLba
  )
{
  EFI_BLOCK_IO_PROTOCOL     *BlkIo;
  EFI_FILE                  *FileHandle;
  VOID                      *Buffer;
  VOID                      *TempBuffer;
  UINTN                     BufSize;
  EFI_STATUS                Status;

  Status = GetBlkIOFromName (BlkIoName, &BlkIo);
  if (EFI_ERROR(Status)) {
    Print (L"dumpbs: GetBlkIOFromName fail - %s\n", BlkIoName);
    return Status;
  }

  //
  // Get the File from sector file name
  //
  Status = GetFileHandleFromName (FileName, &FileHandle);
  if (EFI_ERROR(Status)) {
    Print (L"dumpbs: GetFileHandleFromName fail - %s\n", FileName);
    return Status;
  }

  //
  // Init
  //
  BufSize = BOOT_HEADER_SIZE;
  Buffer = AllocatePool (BOOT_HEADER_SIZE);
  ASSERT (Buffer != NULL);
  TempBuffer = AllocatePool (BOOT_HEADER_SIZE);
  ASSERT (TempBuffer != NULL);

  //
  // Write the boot sector to block device from a file
  //

  //
  // Set file pointer to end start position
  //
  Status = FileHandle->SetPosition (FileHandle, 0);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: Set %hs pos error - %r\n", FileName, Status);
    goto Done;
  }

  //
  // Read data from file
  //
  Status = FileHandle->Read (FileHandle, &BufSize, Buffer);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: - Read error - %r\n", Status);
    goto Done;
  }

  //
  // Whether Boot sector file size is 512
  //
  if (BufSize != BOOT_HEADER_SIZE) {
    Print(L"dumpbs: Error, Boot sector file is smaller than %d bytes\n", BOOT_HEADER_SIZE);
    Status = EFI_ABORTED;
    goto Done;
  }

  //
  // Read block device's boot sector to TempBuffer
  //      
  Status = BlkIo->ReadBlocks (BlkIo, BlkIo->Media->MediaId, StartingLba, BOOT_HEADER_SIZE, TempBuffer);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: Read boot sector error - %r\n", Status);
    goto Done;
  }

  //
  // Update target buffer
  //
  PatchBlock (Buffer, TempBuffer, FALSE);

  //
  // Finnally write the boot sector
  //
  Status = BlkIo->WriteBlocks (BlkIo, BlkIo->Media->MediaId, StartingLba, BOOT_HEADER_SIZE, Buffer);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: Write boot sector error - %r\n", Status);
    goto Done;
  }

  Print(L"dumpbs: Write boot sector finished\n");

Done:
  FreePool(TempBuffer);
  FreePool(Buffer);
  FileHandle->Close(FileHandle);

  return Status;
}

EFI_STATUS
ReadBootSector (
  IN CHAR16       *BlkIoName,
  IN CHAR16       *FileName,
  IN UINT64       StartingLba
  )
{
  EFI_BLOCK_IO_PROTOCOL     *BlkIo;
  EFI_FILE                  *FileHandle;
  VOID                      *Buffer;
  UINTN                     BufSize;
  EFI_STATUS                Status;

  Status = GetBlkIOFromName (BlkIoName, &BlkIo);
  if (EFI_ERROR(Status)) {
    Print (L"dumpbs: GetBlkIOFromName fail - %s\n", BlkIoName);
    return Status;
  }

  //
  // Get the File from sector file name
  //
  Status = GetFileHandleFromName (FileName, &FileHandle);
  if (EFI_ERROR(Status)) {
    Print (L"dumpbs: GetFileHandleFromName fail - %s\n", FileName);
    return Status;
  }

  //
  // Init
  //
  BufSize = BOOT_HEADER_SIZE;
  Buffer = AllocatePool (BOOT_HEADER_SIZE);
  ASSERT (Buffer != NULL);

  //
  // Dump the boot sector to file from a block device
  //

  //
  // Read the block device's boot sector
  //
  Status = BlkIo->ReadBlocks (BlkIo, BlkIo->Media->MediaId, StartingLba, BOOT_HEADER_SIZE, Buffer);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: Read boot sector error - %r\n", Status);
    goto Done;
  }

  //
  // Set file pointer to end start position
  //
  Status = FileHandle->SetPosition (FileHandle, 0);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: Set %hs pos error - %r\n", FileName, Status);
    goto Done;
  }

  //
  // Write the boot sector to file
  //
  Status = FileHandle->Write (FileHandle, &BufSize, Buffer);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: - Write error - %r\n", Status);
    goto Done;
  }

  //
  // Boot sector file is smaller than 512 bytes
  //
  if (BufSize != BOOT_HEADER_SIZE) {
    Print(L"dumpbs: Boot sector file is smaller than %d bytes\n", BOOT_HEADER_SIZE);
    Status = EFI_ABORTED;
    goto Done;
  }

  Print(L"dumpbs: Dump boot sector successfully\n");

Done:
  FreePool(Buffer);
  FileHandle->Close(FileHandle);

  return Status;
}

EFI_STATUS
ReadBootSectorAndPatch (
  IN CHAR16       *BlkIoName,
  IN CHAR16       *FileName,
  IN UINT64       StartingLba
  )
{
  EFI_BLOCK_IO_PROTOCOL     *BlkIo;
  EFI_FILE                  *FileHandle;
  VOID                      *Buffer;
  VOID                      *TempBuffer;
  UINTN                     BufSize;
  EFI_STATUS                Status;

  Status = GetBlkIOFromName (BlkIoName, &BlkIo);
  if (EFI_ERROR(Status)) {
    Print (L"dumpbs: GetBlkIOFromName fail - %s\n", BlkIoName);
    return Status;
  }

  //
  // Get the File from sector file name
  //
  Status = GetFileHandleFromName (FileName, &FileHandle);
  if (EFI_ERROR(Status)) {
    Print (L"dumpbs: GetFileHandleFromName fail - %s\n", FileName);
    return Status;
  }

  //
  // Init
  //
  BufSize = BOOT_HEADER_SIZE;
  Buffer = AllocatePool (BOOT_HEADER_SIZE);
  ASSERT (Buffer != NULL);
  TempBuffer = AllocatePool (BOOT_HEADER_SIZE);
  ASSERT (TempBuffer != NULL);

  //
  // Dump the boot sector to file from a block device
  //

  //
  // Read the block device's boot sector
  //
  Status = BlkIo->ReadBlocks (BlkIo, BlkIo->Media->MediaId, StartingLba, BOOT_HEADER_SIZE, Buffer);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: Read boot sector error - %r\n", Status);
    goto Done;
  }

  //
  // Set file pointer to end start position
  //
  Status = FileHandle->SetPosition (FileHandle, 0);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: Set %hs pos error - %r\n", FileName, Status);
    goto Done;
  }

  //
  // Read data from file
  //    
  Status = FileHandle->Read (FileHandle, &BufSize, TempBuffer);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: - Read error - %r\n", Status);
    goto Done;
  }
      
  //
  // Whether Boot sector file size is 512
  //
  if (BufSize < BOOT_HEADER_SIZE) {
    Print(L"dumpbs: Error, Boot sector file is smaller than %d bytes\n", BOOT_HEADER_SIZE);
    Status = EFI_ABORTED;
    goto Done;
  }
      
  //
  // Update target buffer
  //
  PatchBlock (TempBuffer, Buffer, FALSE);

  //
  // Set file pointer to end start position
  //
  Status = FileHandle->SetPosition (FileHandle, 0);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: Set %hs pos error - %r\n", FileName, Status);
    goto Done;
  }

  //
  // Write the boot sector to file
  //
  Status = FileHandle->Write (FileHandle, &BufSize, TempBuffer);
  if (EFI_ERROR(Status)) {
    Print(L"dumpbs: - Write error - %r\n", Status);
    goto Done;
  }

  //
  // Boot sector file is smaller than 512 bytes
  //
  if (BufSize != BOOT_HEADER_SIZE) {
    Print(L"dumpbs: Boot sector file is smaller than %d bytes\n", BOOT_HEADER_SIZE);
    Status = EFI_ABORTED;
    goto Done;
  }

  Print(L"dumpbs: Dump boot sector successfully\n");

Done:
  FreePool(TempBuffer);
  FreePool(Buffer);
  FileHandle->Close(FileHandle);

  return Status;
}

EFI_STATUS
AutomaticalPatch (
  IN UINTN                     Argc,
  IN CHAR16                    **Argv
  )
{
  UINT64       BootSectorLba;
  EFI_STATUS   Status;

  //
  // Get BootSectorLba
  //
  BootSectorLba = ShowBootSectorLbaOffset (Argv[2], Atoi(Argv[3]));
  if (BootSectorLba == 0) {
    Print (L"dumpbs: BootSectorLba invalid for parititon %d\n", Argv[3]);
    return EFI_INVALID_PARAMETER;
  }

  //
  // Prepare Efildr file
  //
  Status = ReadBootSectorAndPatch (Argv[2], Argv[4], BootSectorLba);
  if (EFI_ERROR(Status)) {
    return Status;
  }
  Status = PatchBootSectorLbaOffset (BootSectorLba, Argv[4]);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Prepare BootSector file
  //
  Status = ReadBootSectorAndPatch (Argv[2], Argv[5], BootSectorLba);
  if (EFI_ERROR(Status)) {
    return Status;
  }
  Status = PatchBootSectorLbaOffset (BootSectorLba, Argv[5]);
  if (EFI_ERROR(Status)) {
    return Status;
  }
  Status = WriteBootSector (Argv[2], Argv[5], BootSectorLba);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Write GPT MBR (optionally)
  //
  if (Argc == 7) {
    Status = WriteMbr (Argv[2], Argv[6]);
  }

  return Status;
}

//
// Internal Library
//

EFI_STATUS
GetBlkIOFromName (
  IN  CHAR16                        *BlockIdName,
  OUT EFI_BLOCK_IO_PROTOCOL         **BlkIo
  )
/*++

Routine Description:

Arguments:
    
  BlockIdName           Pointer to the block device name
  BlkIo                 Returned block IO

Returns:

  EFI_SUCCESS             Get BlkIo successful
  EFI_INVALID_PARAMETER   Invalid BlockIdName

--*/
{
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_STATUS                Status;
    
  DevicePath  = NULL;
  
  //
  // Get the device path from block device id
  //
  DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)ShellGetMap (BlockIdName);
  if (DevicePath == NULL) {
    Print(L"dumpbs: Invalid block id \"%hs\"\n", BlockIdName);
    return EFI_INVALID_PARAMETER;
  }
  
  //
  // Get the block io from device path
  //
  Status = LibDevicePathToInterface (&gEfiBlockIoProtocolGuid, DevicePath, (VOID **)BlkIo);
  if (EFI_ERROR(Status)) {
    Print (L"dumpbs: Device is not a BlockIo device - %r\n", Status);
    return Status;
  }
  
  return EFI_SUCCESS;
}

EFI_STATUS
GetFileHandleFromName (
  IN  CHAR16                        *FileName,
  OUT EFI_FILE                      **FileHandle
  )
/*++

Routine Description:

Arguments:
    
  FileName              Pointer to the file name
  FileHandle            Returned file handle

Returns:

  EFI_SUCCESS             Get FileHandle successful
  EFI_INVALID_PARAMETER   Invalid FileName

--*/
{
  EFI_LOADED_IMAGE_PROTOCOL             *Image;
  EFI_DEVICE_PATH_PROTOCOL              *DevicePath;
  EFI_HANDLE                            DeviceHandle;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL       *SimpleFileSystem;
  static EFI_FILE                       *mRoot = NULL;
  EFI_STATUS                            Status;
 
  if (mRoot == NULL) {
    Status = BS->HandleProtocol (
                   mImageHandle,
                   &gEfiLoadedImageProtocolGuid,
                   &Image
                   );
    if (EFI_ERROR(Status)) {
      Print (L"Error: HandleProtocol LoadedImage ! - %r\n", Status);
      return EFI_INVALID_PARAMETER;
    }
    Status = BS->HandleProtocol (
                   Image->DeviceHandle,
                   &gEfiDevicePathProtocolGuid,
                   &DevicePath
                   );
    if (EFI_ERROR(Status)) {
      Print (L"Error: HandleProtocol DevicePath ! - %r\n", Status);
      return EFI_INVALID_PARAMETER;
    }
    Status = BS->LocateDevicePath ( 
                   &gEfiSimpleFileSystemProtocolGuid,
                   &DevicePath,
                   &DeviceHandle
                   );
    if (EFI_ERROR (Status)) {
      Print (L"Error: LocateDevicePath SimpleFileSystem ! - %r\n", Status);
      return EFI_INVALID_PARAMETER;
    }

    Status = BS->HandleProtocol (
                   DeviceHandle, 
                   &gEfiSimpleFileSystemProtocolGuid,
                   (VOID*)&SimpleFileSystem
                   );
    if (EFI_ERROR (Status)) {
      Print (L"Error: HandleProtocol SimpleFileSystem ! - %r\n", Status);
      return EFI_INVALID_PARAMETER;
    }
    Status = SimpleFileSystem->OpenVolume (
                                 SimpleFileSystem,
                                 &mRoot
                                 );
    if (EFI_ERROR (Status)) {
      Print (L"Error: SimpleFileSystem->OpenVolume() ! - %r\n", Status);
      return EFI_INVALID_PARAMETER;
    }
  }
  
  Status = mRoot->Open (
                   mRoot,
                   FileHandle,
                   FileName,
                   EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
                   0
                   );
  if (EFI_ERROR (Status)) {
    Print (L"Error: mRoot->Open() ! - %r\n", Status);
    return EFI_INVALID_PARAMETER;
  }
  
  return EFI_SUCCESS;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?