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 + -
显示快捷键?