winntblockio.c

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

C
1,122
字号
          );
  }

  return Status;
}

STATIC
EFI_STATUS
WinNtBlockIoReadWriteCommon (
  IN  WIN_NT_BLOCK_IO_PRIVATE     *Private,
  IN UINT32                       MediaId,
  IN EFI_LBA                      Lba,
  IN UINTN                        BufferSize,
  IN VOID                         *Buffer,
  IN CHAR8                        *CallerName
  )
/*++

Routine Description:

  TODO: Add function description

Arguments:

  Private     - TODO: add argument description
  MediaId     - TODO: add argument description
  Lba         - TODO: add argument description
  BufferSize  - TODO: add argument description
  Buffer      - TODO: add argument description
  CallerName  - TODO: add argument description

Returns:

  EFI_NO_MEDIA - TODO: Add description for return value
  EFI_MEDIA_CHANGED - TODO: Add description for return value
  EFI_INVALID_PARAMETER - TODO: Add description for return value
  EFI_SUCCESS - TODO: Add description for return value
  EFI_BAD_BUFFER_SIZE - TODO: Add description for return value
  EFI_INVALID_PARAMETER - TODO: Add description for return value
  EFI_SUCCESS - TODO: Add description for return value

--*/
{
  EFI_STATUS  Status;
  UINTN       BlockSize;
  UINT64      LastBlock;
  INT64       DistanceToMove;
  UINT64      DistanceMoved;

  if (Private->NtHandle == INVALID_HANDLE_VALUE) {
    Status = WinNtBlockIoOpenDevice (Private);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  if (!Private->Media.MediaPresent) {
    DEBUG ((EFI_D_INIT, "%s: No Media\n", CallerName));
    return EFI_NO_MEDIA;
  }

  if (Private->Media.MediaId != MediaId) {
    return EFI_MEDIA_CHANGED;
  }

  if ((UINT32) Buffer % Private->Media.IoAlign != 0) {
    return EFI_INVALID_PARAMETER;
  }
  
  //
  // Verify buffer size
  //
  BlockSize = Private->BlockSize;
  if (BufferSize == 0) {
    DEBUG ((EFI_D_INIT, "%s: Zero length read\n", CallerName));
    return EFI_SUCCESS;
  }

  if ((BufferSize % BlockSize) != 0) {
    DEBUG ((EFI_D_INIT, "%s: Invalid read size\n", CallerName));
    return EFI_BAD_BUFFER_SIZE;
  }

  LastBlock = Lba + (BufferSize / BlockSize) - 1;
  if (LastBlock > Private->LastBlock) {
    DEBUG ((EFI_D_INIT, "ReadBlocks: Attempted to read off end of device\n"));
    return EFI_INVALID_PARAMETER;
  }
  //
  // Seek to End of File
  //
  DistanceToMove = MultU64x32 (Lba, BlockSize);
  Status = SetFilePointer64 (Private, DistanceToMove, &DistanceMoved, FILE_BEGIN);

  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_INIT, "WriteBlocks: SetFilePointer failed\n"));
    return WinNtBlockIoError (Private);
  }

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
WinNtBlockIoReadBlocks (
  IN EFI_BLOCK_IO_PROTOCOL  *This,
  IN UINT32                 MediaId,
  IN EFI_LBA                Lba,
  IN UINTN                  BufferSize,
  OUT VOID                  *Buffer
  )
/*++

  Routine Description:
    Read BufferSize bytes from Lba into Buffer.

  Arguments:
    This       - Protocol instance pointer.
    MediaId    - Id of the media, changes every time the media is replaced.
    Lba        - The starting Logical Block Address to read from
    BufferSize - Size of Buffer, must be a multiple of device block size.
    Buffer     - Buffer containing read data

  Returns:
    EFI_SUCCESS           - The data was read correctly from the device.
    EFI_DEVICE_ERROR      - The device reported an error while performing the read.
    EFI_NO_MEDIA          - There is no media in the device.
    EFI_MEDIA_CHANGED     - The MediaId does not matched the current device.
    EFI_BAD_BUFFER_SIZE   - The Buffer was not a multiple of the block size of the 
                            device.
    EFI_INVALID_PARAMETER - The read request contains device addresses that are not 
                            valid for the device.

--*/
{
  WIN_NT_BLOCK_IO_PRIVATE *Private;
  BOOL                    Flag;
  EFI_STATUS              Status;
  DWORD                   BytesRead;

  Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);

  Status  = WinNtBlockIoReadWriteCommon (Private, MediaId, Lba, BufferSize, Buffer, "WinNtReadBlocks");
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Flag = Private->WinNtThunk->ReadFile (Private->NtHandle, Buffer, (DWORD) BufferSize, (LPDWORD) &BytesRead, NULL);
  if (!Flag || (BytesRead != BufferSize)) {
    DEBUG ((EFI_D_INIT, "ReadBlocks: ReadFile failed. (%d)\n", Private->WinNtThunk->GetLastError ()));
    return WinNtBlockIoError (Private);
  }

  //
  // If we wrote then media is present.
  //
  This->Media->MediaPresent = TRUE;
  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
WinNtBlockIoWriteBlocks (
  IN EFI_BLOCK_IO_PROTOCOL  *This,
  IN UINT32                 MediaId,
  IN EFI_LBA                Lba,
  IN UINTN                  BufferSize,
  IN VOID                   *Buffer
  )
/*++

  Routine Description:
    Write BufferSize bytes from Lba into Buffer.

  Arguments:
    This       - Protocol instance pointer.
    MediaId    - Id of the media, changes every time the media is replaced.
    Lba        - The starting Logical Block Address to read from
    BufferSize - Size of Buffer, must be a multiple of device block size.
    Buffer     - Buffer containing read data

  Returns:
    EFI_SUCCESS           - The data was written correctly to the device.
    EFI_WRITE_PROTECTED   - The device can not be written to.
    EFI_DEVICE_ERROR      - The device reported an error while performing the write.
    EFI_NO_MEDIA          - There is no media in the device.
    EFI_MEDIA_CHNAGED     - The MediaId does not matched the current device.
    EFI_BAD_BUFFER_SIZE   - The Buffer was not a multiple of the block size of the 
                            device.
    EFI_INVALID_PARAMETER - The write request contains a LBA that is not 
                            valid for the device.

--*/
{
  WIN_NT_BLOCK_IO_PRIVATE *Private;
  UINTN                   BytesWritten;
  BOOL                    Flag;
  EFI_STATUS              Status;

  Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);

  Status  = WinNtBlockIoReadWriteCommon (Private, MediaId, Lba, BufferSize, Buffer, "WinNtWriteBlocks");
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Flag = Private->WinNtThunk->WriteFile (Private->NtHandle, Buffer, (DWORD) BufferSize, (LPDWORD) &BytesWritten, NULL);
  if (!Flag || (BytesWritten != BufferSize)) {
    DEBUG ((EFI_D_INIT, "ReadBlocks: WriteFile failed. (%d)\n", Private->WinNtThunk->GetLastError ()));
    return WinNtBlockIoError (Private);
  }

  //
  // If the write succeeded, we are not write protected and media is present.
  //
  This->Media->MediaPresent = TRUE;
  This->Media->ReadOnly     = FALSE;
  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
WinNtBlockIoFlushBlocks (
  IN EFI_BLOCK_IO_PROTOCOL  *This
  )
/*++

  Routine Description:
    Flush the Block Device.

  Arguments:
    This             - Protocol instance pointer.

  Returns:
    EFI_SUCCESS      - All outstanding data was written to the device
    EFI_DEVICE_ERROR - The device reported an error while writting back the data
    EFI_NO_MEDIA     - There is no media in the device.

--*/
{
  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
WinNtBlockIoResetBlock (
  IN EFI_BLOCK_IO_PROTOCOL  *This,
  IN BOOLEAN                ExtendedVerification
  )
/*++

  Routine Description:
    Reset the Block Device.

  Arguments:
    This                 - Protocol instance pointer.
    ExtendedVerification - Driver may perform diagnostics on reset.

  Returns:
    EFI_SUCCESS           - The device was reset.
    EFI_DEVICE_ERROR      - The device is not functioning properly and could 
                            not be reset.

--*/
{
  WIN_NT_BLOCK_IO_PRIVATE *Private;

  Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);

  if (Private->NtHandle != INVALID_HANDLE_VALUE) {
    Private->WinNtThunk->CloseHandle (Private->NtHandle);
    Private->NtHandle = INVALID_HANDLE_VALUE;
  }

  return EFI_SUCCESS;
}

UINTN
Atoi (
  CHAR16  *String
  )
/*++

Routine Description:

  Convert a unicode string to a UINTN

Arguments:

  String - Unicode string.

Returns: 

  UINTN of the number represented by String.  

--*/
{
  UINTN   Number;
  CHAR16  *Str;

  //
  // skip preceeding white space
  //
  Str = String;
  while ((*Str) && (*Str == ' ')) {
    Str++;
  }
  //
  // Convert ot a Number
  //
  Number = 0;
  while (*Str != '\0') {
    if ((*Str >= '0') && (*Str <= '9')) {
      Number = (Number * 10) +*Str - '0';
    } else {
      break;
    }

    Str++;
  }

  return Number;
}

EFI_STATUS
SetFilePointer64 (
  IN  WIN_NT_BLOCK_IO_PRIVATE    *Private,
  IN  INT64                      DistanceToMove,
  OUT UINT64                     *NewFilePointer,
  IN  DWORD                      MoveMethod
  )
/*++

This function extends the capability of SetFilePointer to accept 64 bit parameters

--*/
// TODO: function comment is missing 'Routine Description:'
// TODO: function comment is missing 'Arguments:'
// TODO: function comment is missing 'Returns:'
// TODO:    Private - add argument and description to function comment
// TODO:    DistanceToMove - add argument and description to function comment
// TODO:    NewFilePointer - add argument and description to function comment
// TODO:    MoveMethod - add argument and description to function comment
{
  EFI_STATUS    Status;
  LARGE_INTEGER LargeInt;
  UINT32        ErrorCode;

  LargeInt.QuadPart = DistanceToMove;
  Status            = EFI_SUCCESS;

  LargeInt.LowPart = Private->WinNtThunk->SetFilePointer (
                                            Private->NtHandle,
                                            LargeInt.LowPart,
                                            &LargeInt.HighPart,
                                            MoveMethod
                                            );

  if (LargeInt.LowPart == -1 &&
      (ErrorCode = Private->WinNtThunk->GetLastError ()) != NO_ERROR) {
    Status = EFI_INVALID_PARAMETER;
  }

  if (NewFilePointer != NULL) {
    *NewFilePointer = LargeInt.QuadPart;
  }

  return Status;
}

⌨️ 快捷键说明

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