mtftp4impl.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 930 行 · 第 1/2 页
C
930 行
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Mtftp4Impl.c
Abstract:
Interface routine for Mtftp4
--*/
#include "Mtftp4Impl.h"
STATIC
EFI_STATUS
EFIAPI
EfiMtftp4ReadFile (
IN EFI_MTFTP4_PROTOCOL *This,
IN EFI_MTFTP4_TOKEN *Token
);
STATIC
EFI_STATUS
EFIAPI
EfiMtftp4GetModeData (
IN EFI_MTFTP4_PROTOCOL *This,
OUT EFI_MTFTP4_MODE_DATA *ModeData
)
/*++
Routine Description:
Get the current operation parameter for the MTFTP session
Arguments:
This - The MTFTP protocol instance
ModeData - The MTFTP mode data
Returns:
EFI_INVALID_PARAMETER - This or ModeData is NULL
EFI_SUCCESS - The operation parameter is saved in ModeData
--*/
{
MTFTP4_PROTOCOL *Instance;
if ((This == NULL) || (ModeData == NULL)) {
return EFI_INVALID_PARAMETER;
}
Instance = MTFTP4_PROTOCOL_FROM_THIS (This);
ModeData->ConfigData = Instance->Config;
ModeData->SupportedOptionCount = MTFTP4_SUPPORTED_OPTIONS;
ModeData->SupportedOptoins = mMtftp4SupportedOptions;
ModeData->UnsupportedOptionCount = 0;
ModeData->UnsupportedOptoins = NULL;
return EFI_SUCCESS;
}
VOID
Mtftp4CleanOperation (
IN MTFTP4_PROTOCOL *Instance,
IN EFI_STATUS Result
)
/*++
Routine Description:
Clean up the MTFTP session to get ready for new operation.
Arguments:
Instance - The MTFTP session to clean up
Result - The result to return to the caller who initiated the operation.
Returns:
None
--*/
{
NET_LIST_ENTRY *Entry;
NET_LIST_ENTRY *Next;
MTFTP4_BLOCK_RANGE *Block;
EFI_MTFTP4_TOKEN *Token;
//
// Free various resources.
//
Token = Instance->Token;
if (Token != NULL) {
Token->Status = Result;
if (Token->Event != NULL) {
gBS->SignalEvent (Token->Event);
}
Instance->Token = NULL;
}
ASSERT (Instance->UnicastPort != NULL);
UdpIoCleanPort (Instance->UnicastPort);
if (Instance->LastPacket != NULL) {
NetbufFree (Instance->LastPacket);
Instance->LastPacket = NULL;
}
if (Instance->McastUdpPort != NULL) {
UdpIoFreePort (Instance->McastUdpPort);
Instance->McastUdpPort = NULL;
}
NET_LIST_FOR_EACH_SAFE (Entry, Next, &Instance->Blocks) {
Block = NET_LIST_USER_STRUCT (Entry, MTFTP4_BLOCK_RANGE, Link);
NetListRemoveEntry (Entry);
NetFreePool (Block);
}
NetZeroMem (&Instance->RequestOption, sizeof (MTFTP4_OPTION));
Instance->Operation = 0;
Instance->BlkSize = MTFTP4_DEFAULT_BLKSIZE;
Instance->LastBlock = 0;
Instance->ServerIp = 0;
Instance->ListeningPort = 0;
Instance->ConnectedPort = 0;
Instance->Gateway = 0;
Instance->PacketToLive = 0;
Instance->MaxRetry = 0;
Instance->CurRetry = 0;
Instance->Timeout = 0;
Instance->McastIp = 0;
Instance->McastPort = 0;
Instance->Master = TRUE;
}
STATIC
EFI_STATUS
EFIAPI
EfiMtftp4Configure (
IN EFI_MTFTP4_PROTOCOL *This,
IN EFI_MTFTP4_CONFIG_DATA *ConfigData
)
/*++
Routine Description:
Configure the MTFTP session for new operation or reset the current
operation if ConfigData is NULL.
Arguments:
This - The MTFTP session to configure
ConfigData - The configure parameters
Returns:
EFI_INVALID_PARAMETER - Some of the parameter is invalid.
EFI_ACCESS_DENIED - There is pending operation
EFI_SUCCESS - The instance is configured for operation.
--*/
{
MTFTP4_PROTOCOL *Instance;
EFI_TPL OldTpl;
IP4_ADDR Ip;
IP4_ADDR Netmask;
IP4_ADDR Gateway;
if (This == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = MTFTP4_PROTOCOL_FROM_THIS (This);
if (ConfigData == NULL) {
//
// Reset the operation if ConfigData is NULL
//
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
Mtftp4CleanOperation (Instance, EFI_ABORTED);
NetZeroMem (&Instance->Config, sizeof (EFI_MTFTP4_CONFIG_DATA));
Instance->State = MTFTP4_STATE_UNCONFIGED;
NET_RESTORE_TPL (OldTpl);
} else {
//
// Configure the parameters for new operation.
//
Ip = EFI_NTOHL (ConfigData->StationIp);
Netmask = EFI_NTOHL (ConfigData->SubnetMask);
Gateway = EFI_NTOHL (ConfigData->GatewayIp);
if (!Ip4IsUnicast (EFI_NTOHL (ConfigData->ServerIp), 0)) {
return EFI_INVALID_PARAMETER;
}
if (!ConfigData->UseDefaultSetting &&
((!IP4_IS_VALID_NETMASK (Netmask) || !Ip4IsUnicast (Ip, Netmask)))) {
return EFI_INVALID_PARAMETER;
}
if ((Gateway != 0) &&
(!IP4_NET_EQUAL (Gateway, Ip, Netmask) || !Ip4IsUnicast (Gateway, Netmask))) {
return EFI_INVALID_PARAMETER;
}
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
if ((Instance->State == MTFTP4_STATE_CONFIGED) && (Instance->Operation != 0)) {
NET_RESTORE_TPL (OldTpl);
return EFI_ACCESS_DENIED;
}
Instance->Config = *ConfigData;
Instance->State = MTFTP4_STATE_CONFIGED;
NET_RESTORE_TPL (OldTpl);
}
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
Mtftp4GetInfoCheckPacket (
IN EFI_MTFTP4_PROTOCOL *This,
IN EFI_MTFTP4_TOKEN *Token,
IN UINT16 PacketLen,
IN EFI_MTFTP4_PACKET *Packet
)
/*++
Routine Description:
Check packet for GetInfo. GetInfo is implemented with EfiMtftp4ReadFile.
It use Mtftp4GetInfoCheckPacket to inspect the first packet from server,
then abort the session.
Arguments:
This - The MTFTP4 protocol instance
Token - The user's token
PacketLen - The length of the packet
Packet - The received packet.
Returns:
EFI_ABORTED - Abort the ReadFile operation and return.
--*/
{
MTFTP4_GETINFO_STATE *State;
EFI_STATUS Status;
UINT16 OpCode;
State = (MTFTP4_GETINFO_STATE *) Token->Context;
OpCode = NTOHS (Packet->OpCode);
//
// Set the GetInfo's return status according to the OpCode.
//
switch (OpCode) {
case EFI_MTFTP4_OPCODE_ERROR:
State->Status = EFI_TFTP_ERROR;
break;
case EFI_MTFTP4_OPCODE_OACK:
State->Status = EFI_SUCCESS;
break;
default:
State->Status = EFI_PROTOCOL_ERROR;
}
//
// Allocate buffer then copy the packet over. Use gBS->AllocatePool
// in case NetAllocatePool will implements something tricky.
//
Status = gBS->AllocatePool (EfiBootServicesData, PacketLen, State->Packet);
if (EFI_ERROR (Status)) {
State->Status = EFI_OUT_OF_RESOURCES;
return EFI_ABORTED;
}
*(State->PacketLen) = PacketLen;
NetCopyMem (*(State->Packet), Packet, PacketLen);
return EFI_ABORTED;
}
STATIC
EFI_STATUS
EFIAPI
EfiMtftp4GetInfo (
IN EFI_MTFTP4_PROTOCOL *This,
IN EFI_MTFTP4_OVERRIDE_DATA *OverrideData, OPTIONAL
IN UINT8 *Filename,
IN UINT8 *ModeStr, OPTIONAL
IN UINT8 OptionCount,
IN EFI_MTFTP4_OPTION *OptionList,
OUT UINT32 *PacketLength,
OUT EFI_MTFTP4_PACKET **Packet OPTIONAL
)
/*++
Routine Description:
Get the information of the download from the server. It is implemented
with EfiMtftp4ReadFile: build a token, then pass it to EfiMtftp4ReadFile.
In its check packet callback abort the opertions.
Arguments:
This - The MTFTP protocol instance
OverrideData - The MTFTP override data
Filename - The file to get information
ModeStr - The mode to use
OptionCount - The number of options to append
OptionList - The options to append
PacketLength - The variable to receive the packet length
Packet - The variable to receive the packet.
Returns:
EFI_INVALID_PARAMETER - The parameter is invaid
EFI_SUCCESS - The information is got
Others - Failed to get the information.
--*/
{
EFI_MTFTP4_TOKEN Token;
MTFTP4_GETINFO_STATE State;
EFI_STATUS Status;
if ((This == NULL) || (Filename == NULL) || (PacketLength == NULL) ||
(OptionCount && (OptionList == NULL))) {
return EFI_INVALID_PARAMETER;
}
if (Packet != NULL) {
*Packet = NULL;
}
*PacketLength = 0;
State.Packet = Packet;
State.PacketLen = PacketLength;
State.Status = EFI_SUCCESS;
//
// Fill in the Token to issue an synchronous ReadFile operation
//
Token.Status = EFI_SUCCESS;
Token.Event = NULL;
Token.OverrideData = OverrideData;
Token.Filename = Filename;
Token.ModeStr = ModeStr;
Token.OptionCount = OptionCount;
Token.OptionList = OptionList;
Token.BufferSize = 0;
Token.Buffer = NULL;
Token.Context = &State;
Token.CheckPacket = Mtftp4GetInfoCheckPacket;
Token.TimeoutCallback = NULL;
Token.PacketNeeded = NULL;
Status = EfiMtftp4ReadFile (This, &Token);
if (EFI_ABORTED == Status) {
return State.Status;
}
return Status;
}
STATIC
EFI_STATUS
EFIAPI
EfiMtftp4ParseOptions (
IN EFI_MTFTP4_PROTOCOL *This,
IN UINT32 PacketLen,
IN EFI_MTFTP4_PACKET *Packet,
IN OUT UINT32 *OptionCount,
OUT EFI_MTFTP4_OPTION **OptionList OPTIONAL
)
/*++
Routine Description:
Parse the packet into an array of options. The OptionList is allocated
by this function, and caller should free it when used.
Arguments:
This - The MTFTP protocol instance
PacketLen - The length of the packet
Packet - The packet to parse
OptionCount - The size of the OptionList array allocated.
OptionList - The allocated option array to save the option addresses.
Returns:
EFI_INVALID_PARAMETER - The parameters are invalid.
EFI_NOT_FOUND - There is no valid option in the packet
EFI_SUCCESS - The packet is parsed.
--*/
{
EFI_STATUS Status;
if ((This == NULL) || (PacketLen < MTFTP4_OPCODE_LEN) ||
(Packet == NULL) || (OptionCount == NULL)) {
return EFI_INVALID_PARAMETER;
}
Status = Mtftp4ExtractOptions (Packet, PacketLen, OptionCount, OptionList);
if (EFI_ERROR (Status)) {
return Status;
}
if (*OptionCount == 0) {
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
STATIC
BOOLEAN
Mtftp4OverrideValid (
IN MTFTP4_PROTOCOL *Instance,
IN EFI_MTFTP4_OVERRIDE_DATA *Override
)
/*++
Routine Description:
Check whether the override data is valid. It will first
validate whether the server is a valid unicast. If a gateway
is provided in the Override, it also check that it is a
unicast on the connected network.
Arguments:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?