pxe_bc_mtftp.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,396 行 · 第 1/5 页
C
2,396 行
} while (Status == EFI_TIMEOUT && --Retries);
if (Status != EFI_SUCCESS) {
return Status;
}
BufferPtr = (VOID *) ((UINT8 *) (BufferPtr) + TransferLen);
TransferSize -= TransferLen;
++BlockNum;
Header.BlockNum = HTONS ((UINT16) BlockNum);
} while (TransferLen == *PacketSizePtr);
return EFI_SUCCESS;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
EFI_STATUS
PxeBcMtftp (
PXE_BASECODE_DEVICE *Private,
IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation,
UINT64 *BufferSizePtr,
VOID *BufferPtr,
EFI_IP_ADDRESS *ServerIpPtr,
UINT8 *FilenamePtr,
UINTN *PacketSizePtr,
IN EFI_PXE_BASE_CODE_MTFTP_INFO *MtftpInfoPtr, OPTIONAL
IN BOOLEAN Overwrite,
IN BOOLEAN DontUseBuffer
)
/*++
Routine description:
MTFTP API entry point
Parameters:
Private :=
Operation :=
BufferSizePtr :=
BufferPtr :=
ServerIpPtr :=
FilenamePtr :=
PacketSizePtr :=
MtftpInfoPtr :=
Overwrite :=
DontUseBuffer :=
Returns:
* EFI_INVALID_PARAMETER
* EFI_OUT_OF_RESOURCES
* EFI_BAD_BUFFER_SIZE
* Status is also returned from IpFilter(), TftpInfo(), MtftpDownload(),
* TftpDownload() and TftpUpload().
--*/
{
EFI_PXE_BASE_CODE_IP_FILTER Filter;
EFI_STATUS StatCode;
EFI_STATUS Status;
UINT64 BufferSizeLocal;
UINTN PacketSize;
UINT8 *BufferPtrLocal;
Filter.Filters = EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP;
Filter.IpCnt = 0;
Filter.reserved = 0;
/* No error has occurred, yet. */
Private->EfiBc.Mode->TftpErrorReceived = FALSE;
/* We must at least have an MTFTP server IP address and
* a pointer to the buffer size.
*/
if (!ServerIpPtr || !BufferSizePtr) {
DEBUG ((EFI_D_WARN, "\nPxeBcMtftp() Exit #1"));
return EFI_INVALID_PARAMETER;
}
Private->Function = EFI_PXE_BASE_CODE_FUNCTION_MTFTP;
//
// make sure filter set to unicast at start
//
if ((StatCode = IpFilter (Private, &Filter)) != EFI_SUCCESS) {
DEBUG (
(EFI_D_NET,
"\nPxeBcMtftp() Exit IpFilter() == %Xh",
StatCode)
);
return StatCode;
}
//
// set unset parms to default values
//
if (!PacketSizePtr) {
*(PacketSizePtr = &PacketSize) = MAX_TFTP_PKT_SIZE;
}
if (*PacketSizePtr > *BufferSizePtr) {
*PacketSizePtr = (UINTN) *BufferSizePtr;
}
if (*PacketSizePtr < MIN_TFTP_PKT_SIZE) {
*PacketSizePtr = MIN_TFTP_PKT_SIZE;
}
if (*PacketSizePtr > BUFFER_ALLOCATE_SIZE) {
*PacketSizePtr = BUFFER_ALLOCATE_SIZE;
}
if (*PacketSizePtr > MAX_TFTP_PKT_SIZE) {
*PacketSizePtr = MAX_TFTP_PKT_SIZE;
}
if (Operation == EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE) {
StatCode = TftpInfo (
Private,
BufferSizePtr,
ServerIpPtr,
TftpRequestPort,
FilenamePtr,
PacketSizePtr
);
if (StatCode != EFI_SUCCESS) {
DEBUG (
(EFI_D_WARN,
"\nPxeBcMtftp() Exit TftpInfo() == %Xh",
StatCode)
);
}
return StatCode;
}
if (Operation == EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE) {
if (!MtftpInfoPtr || !MtftpInfoPtr->SPort) {
DEBUG ((EFI_D_WARN, "\nPxeBcMtftp() Exit #2"));
return EFI_INVALID_PARAMETER;
} else {
StatCode = TftpInfo (
Private,
BufferSizePtr,
ServerIpPtr,
MtftpInfoPtr->SPort,
FilenamePtr,
PacketSizePtr
);
gBS->Stall (10000);
if (StatCode != EFI_SUCCESS) {
DEBUG (
(EFI_D_WARN,
"\nPxeBcMtftp() Exit TftpInfo() == %Xh",
StatCode)
);
}
return StatCode;
}
}
if (!BufferPtr && !DontUseBuffer) {
//
// if dontusebuffer is false and no buffer???
//
DEBUG ((EFI_D_WARN, "\nPxeBcMtftp() Exit #3"));
//
// DontUseBuffer can be true only for read_file operation
//
return EFI_INVALID_PARAMETER;
}
if (DontUseBuffer) {
Status = gBS->AllocatePool (
EfiBootServicesData,
BUFFER_ALLOCATE_SIZE,
&BufferPtrLocal
);
if (EFI_ERROR (Status) || BufferPtrLocal == NULL) {
DEBUG ((EFI_D_NET, "\nPxeBcMtftp() Exit #4"));
return EFI_OUT_OF_RESOURCES;
}
BufferSizeLocal = BUFFER_ALLOCATE_SIZE;
} else {
if (!*BufferSizePtr && Operation != EFI_PXE_BASE_CODE_TFTP_WRITE_FILE) {
DEBUG ((EFI_D_WARN, "\nPxeBcMtftp() Exit #5"));
return EFI_BAD_BUFFER_SIZE;
}
BufferPtrLocal = BufferPtr;
BufferSizeLocal = *BufferSizePtr;
}
switch (Operation) {
case EFI_PXE_BASE_CODE_MTFTP_READ_FILE:
if (FilenamePtr == NULL ||
MtftpInfoPtr == NULL ||
MtftpInfoPtr->MCastIp.Addr[0] == 0 ||
MtftpInfoPtr->SPort == 0 ||
MtftpInfoPtr->CPort == 0 ||
MtftpInfoPtr->ListenTimeout == 0 ||
MtftpInfoPtr->TransmitTimeout == 0
) {
StatCode = EFI_INVALID_PARAMETER;
break;
}
//
// try MTFTP - if fails, drop into TFTP read
//
if ((StatCode = MtftpDownload (
Private,
&BufferSizeLocal,
BufferPtrLocal,
ServerIpPtr,
FilenamePtr,
MtftpInfoPtr,
DontUseBuffer
)) == EFI_SUCCESS || StatCode == EFI_BUFFER_TOO_SMALL) {
if (BufferSizePtr /* %% !DontUseBuffer */ ) {
*BufferSizePtr = BufferSizeLocal;
}
break;
}
//
// go back to unicast
//
if ((StatCode = IpFilter (Private, &Filter)) != EFI_SUCCESS) {
break;
}
/* fall thru */
case EFI_PXE_BASE_CODE_TFTP_READ_FILE:
if (FilenamePtr == NULL) {
StatCode = EFI_INVALID_PARAMETER;
break;
}
StatCode = TftpDownload (
Private,
&BufferSizeLocal,
BufferPtrLocal,
ServerIpPtr,
FilenamePtr,
PacketSizePtr,
TftpRequestPort,
TFTP_RRQ,
DontUseBuffer
);
if (StatCode == EFI_SUCCESS || StatCode == EFI_BUFFER_TOO_SMALL) {
if (BufferSizePtr /* !DontUseBuffer */ ) {
*BufferSizePtr = BufferSizeLocal;
}
}
break;
case EFI_PXE_BASE_CODE_TFTP_WRITE_FILE:
if (FilenamePtr == NULL || DontUseBuffer) {
//
// not a valid option
//
StatCode = EFI_INVALID_PARAMETER;
break;
}
StatCode = TftpUpload (
Private,
BufferSizePtr,
BufferPtr,
ServerIpPtr,
FilenamePtr,
PacketSizePtr,
Overwrite
);
if (StatCode != EFI_SUCCESS) {
DEBUG (
(EFI_D_WARN,
"\nPxeBcMtftp() Exit #6 %xh (%r)",
StatCode,
StatCode)
);
}
return StatCode;
case EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY:
if (FilenamePtr == NULL || DontUseBuffer) {
//
// not a valid option
//
StatCode = EFI_INVALID_PARAMETER;
break;
}
StatCode = TftpDownload (
Private,
BufferSizePtr,
BufferPtr,
ServerIpPtr,
FilenamePtr,
PacketSizePtr,
TftpRequestPort,
TFTP_DIR,
DontUseBuffer
);
if (StatCode != EFI_SUCCESS) {
DEBUG (
(EFI_D_WARN,
"\nPxeBcMtftp() Exit #7 %xh (%r)",
StatCode,
StatCode)
);
}
return StatCode;
case EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY:
if (DontUseBuffer) {
StatCode = EFI_INVALID_PARAMETER;
break;
}
if (MtftpInfoPtr == NULL || !MtftpInfoPtr->SPort) {
DEBUG (
(EFI_D_WARN,
"\nPxeBcMtftp() Exit #9 %xh (%r)",
EFI_INVALID_PARAMETER,
EFI_INVALID_PARAMETER)
);
return EFI_INVALID_PARAMETER;
}
StatCode = TftpDownload (
Private,
BufferSizePtr,
BufferPtr,
ServerIpPtr,
(UINT8 *) "/",
PacketSizePtr,
MtftpInfoPtr->SPort,
TFTP_DIR,
DontUseBuffer
);
break;
default:
StatCode = EFI_INVALID_PARAMETER;
}
if (DontUseBuffer) {
gBS->FreePool (BufferPtrLocal);
}
if (StatCode != EFI_SUCCESS) {
DEBUG (
(EFI_D_WARN,
"\nPxeBcMtftp() Exit #8 %xh (%r)",
StatCode,
StatCode)
);
}
gBS->Stall (10000);
return StatCode;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
EFI_STATUS
EFIAPI
BcMtftp (
IN EFI_PXE_BASE_CODE_PROTOCOL * This,
IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation,
IN OUT VOID *BufferPtr,
IN BOOLEAN Overwrite,
IN OUT UINT64 *BufferSizePtr,
IN UINTN *BlockSizePtr OPTIONAL,
IN EFI_IP_ADDRESS * ServerIpPtr,
IN UINT8 *FilenamePtr,
IN EFI_PXE_BASE_CODE_MTFTP_INFO * MtftpInfoPtr OPTIONAL,
IN BOOLEAN DontUseBuffer
)
/*++
Routine description:
MTFTP API entry point.
Parameters:
This :=
Operation :=
BufferPtr :=
Overwrite :=
BufferSizePtr :=
BlockSizePtr :=
ServerIpPtr :=
FilenamePtr :=
MtftpInfoPtr :=
DontUseBuffer :=
Returns:
* EFI_INVALID_PARAMETER
* Status is also returned from PxeBcMtftp();
--*/
{
EFI_PXE_BASE_CODE_IP_FILTER Filter;
EFI_STATUS StatCode;
PXE_BASECODE_DEVICE *Private;
//
// Lock the instance data and make sure started
//
StatCode = EFI_SUCCESS;
if (This == NULL) {
DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));
return EFI_INVALID_PARAMETER;
}
Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);
if (Private == NULL) {
DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));
return EFI_INVALID_PARAMETER;
}
EfiAcquireLock (&Private->Lock);
if (This->Mode == NULL || !This->Mode->Started) {
DEBUG ((EFI_D_ERROR, "BC was not started."));
EfiReleaseLock (&Private->Lock);
return EFI_NOT_STARTED;
}
//
// Issue BC command
//
Filter.Filters = EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP;
Filter.IpCnt = 0;
Filter.reserved = 0;
DEBUG ((EFI_D_WARN, "\nBcMtftp() Op=%d Buf=%Xh", Operation, BufferPtr));
StatCode = PxeBcMtftp (
Private,
Operation,
BufferSizePtr,
BufferPtr,
ServerIpPtr,
FilenamePtr,
BlockSizePtr,
MtftpInfoPtr,
Overwrite,
DontUseBuffer
);
//
// restore to unicast
//
IpFilter (Private, &Filter);
//
// Unlock the instance data
//
EfiReleaseLock (&Private->Lock);
return StatCode;
}
/* eof - PxeBcMtftp.c */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?