mtftp4impl.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 930 行 · 第 1/2 页
C
930 行
Instance - The MTFTP instance
Override - The override data to validate.
Returns:
TRUE if the override data is valid, otherwise FALSE.
--*/
{
EFI_MTFTP4_CONFIG_DATA *Config;
IP4_ADDR Ip;
IP4_ADDR Netmask;
IP4_ADDR Gateway;
if (!Ip4IsUnicast (EFI_NTOHL (Override->ServerIp), 0)) {
return FALSE;
}
Config = &Instance->Config;
Gateway = EFI_NTOHL (Override->GatewayIp);
if (!Config->UseDefaultSetting && (Gateway != 0)) {
Netmask = EFI_NTOHL (Config->SubnetMask);
Ip = EFI_NTOHL (Config->StationIp);
if (!Ip4IsUnicast (Gateway, Netmask) || !IP4_NET_EQUAL (Gateway, Ip, Netmask)) {
return FALSE;
}
}
return TRUE;
}
BOOLEAN
Mtftp4GetMapping (
IN MTFTP4_PROTOCOL *Instance,
IN UDP_IO_PORT *UdpPort,
IN EFI_UDP4_CONFIG_DATA *UdpCfgData
)
/*++
Routine Description:
Poll the UDP to get the IP4 default address, which may be retrieved
by DHCP. The default time out value is 5 seconds. If IP has retrieved
the default address, the UDP is reconfigured.
Arguments:
Instance - The Mtftp instance
UdpPort - The UDP port to poll
UdpCfgData - The UDP configure data to reconfigure the UDP port.
Returns:
TRUE if the default address is retrieved and UDP is reconfigured.
Otherwise FALSE.
--*/
{
MTFTP4_SERVICE *Service;
EFI_IP4_MODE_DATA Ip4Mode;
EFI_UDP4_PROTOCOL *Udp;
ASSERT (Instance->Config.UseDefaultSetting);
Service = Instance->Service;
Udp = UdpPort->Udp;
if (Service->TimeToGetMap == 0) {
Service->TimeToGetMap = MTFTP4_TIME_TO_GETMAP;
}
while (Service->TimeToGetMap != 0) {
Udp->Poll (Udp);
if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip4Mode, NULL, NULL)) &&
Ip4Mode.IsConfigured) {
Udp->Configure (Udp, NULL);
return (BOOLEAN) (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS);
}
}
return FALSE;
}
STATIC
EFI_STATUS
Mtftp4ConfigUnicastPort (
IN UDP_IO_PORT *UdpIo,
IN MTFTP4_PROTOCOL *Instance
)
/*++
Routine Description:
Configure the UDP port for unicast receiving.
Arguments:
UdpIo - The UDP port
Instance - The MTFTP session
Returns:
EFI_SUCCESS - The UDP port is successfully configured for the session
to unicast receive.
--*/
{
EFI_MTFTP4_CONFIG_DATA *Config;
EFI_UDP4_CONFIG_DATA UdpConfig;
EFI_STATUS Status;
Config = &Instance->Config;
UdpConfig.AcceptBroadcast = FALSE;
UdpConfig.AcceptPromiscuous = FALSE;
UdpConfig.AcceptAnyPort = FALSE;
UdpConfig.AllowDuplicatePort = FALSE;
UdpConfig.TypeOfService = 0;
UdpConfig.TimeToLive = 64;
UdpConfig.DoNotFragment = FALSE;
UdpConfig.ReceiveTimeout = 0;
UdpConfig.TransmitTimeout = 0;
UdpConfig.UseDefaultAddress = Config->UseDefaultSetting;
UdpConfig.StationAddress = Config->StationIp;
UdpConfig.SubnetMask = Config->SubnetMask;
UdpConfig.StationPort = 0;
UdpConfig.RemotePort = 0;
EFI_IP4 (UdpConfig.RemoteAddress) = HTONL (Instance->ServerIp);
Status = UdpIo->Udp->Configure (UdpIo->Udp, &UdpConfig);
if ((Status == EFI_NO_MAPPING) && Mtftp4GetMapping (Instance, UdpIo, &UdpConfig)) {
return EFI_SUCCESS;
}
return Status;
}
STATIC
EFI_STATUS
Mtftp4Start (
IN EFI_MTFTP4_PROTOCOL *This,
IN EFI_MTFTP4_TOKEN *Token,
IN UINT16 Operation
)
/*++
Routine Description:
Start the MTFTP session to do the operation, such as read file,
write file, and read directory.
Arguments:
This - The MTFTP session
Token - The token than encapsues the user's request.
Operation - The operation to do
Returns:
EFI_INVALID_PARAMETER - Some of the parameters are invalid.
EFI_NOT_STARTED - The MTFTP session hasn't been configured.
EFI_ALREADY_STARTED - There is pending operation for the session.
EFI_SUCCESS - The operation is successfully started.
--*/
{
MTFTP4_PROTOCOL *Instance;
EFI_MTFTP4_OVERRIDE_DATA *Override;
EFI_MTFTP4_CONFIG_DATA *Config;
EFI_TPL OldTpl;
EFI_STATUS Status;
//
// Validate the parameters
//
if ((This == NULL) || (Token == NULL) || (Token->Filename == NULL) ||
((Token->OptionCount != 0) && (Token->OptionList == NULL))) {
return EFI_INVALID_PARAMETER;
}
//
// User must provide at least one method to collect the data for download.
//
if (((Operation == EFI_MTFTP4_OPCODE_RRQ) || (Operation == EFI_MTFTP4_OPCODE_DIR)) &&
((Token->Buffer == NULL) && (Token->CheckPacket == NULL))) {
return EFI_INVALID_PARAMETER;
}
//
// User must provide at least one method to provide the data for upload.
//
if ((Operation == EFI_MTFTP4_OPCODE_WRQ) &&
((Token->Buffer == NULL) && (Token->PacketNeeded == NULL))) {
return EFI_INVALID_PARAMETER;
}
Instance = MTFTP4_PROTOCOL_FROM_THIS (This);
if (Instance->State != MTFTP4_STATE_CONFIGED) {
return EFI_NOT_STARTED;
}
if (Instance->Operation != 0) {
return EFI_ACCESS_DENIED;
}
//
// Set the Operation now to prevent the application start other
// operations. Don't get the lock or raise TPL here because
// Mtftp4GetMapping, which is called by UdpIoCreatePort, must be
// run below the NET_TPL_CALLBACK
//
Instance->Operation = Operation;
Override = Token->OverrideData;
if ((Override != NULL) && !Mtftp4OverrideValid (Instance, Override)) {
Status = EFI_INVALID_PARAMETER;
goto ON_ERROR;
}
if (Token->OptionCount != 0) {
Status = Mtftp4ParseOption (
Token->OptionList,
Token->OptionCount,
TRUE,
&Instance->RequestOption
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
}
//
// Set the operation parameters from the configuration or override data.
//
Config = &Instance->Config;
Instance->Token = Token;
Instance->BlkSize = MTFTP4_DEFAULT_BLKSIZE;
Instance->ServerIp = EFI_NTOHL (Config->ServerIp);
Instance->ListeningPort = Config->InitialServerPort;
Instance->ConnectedPort = 0;
Instance->Gateway = EFI_NTOHL (Config->GatewayIp);
Instance->MaxRetry = Config->TryCount;
Instance->Timeout = Config->TimeoutValue;
Instance->Master = TRUE;
if (Override != NULL) {
Instance->Gateway = EFI_NTOHL (Override->GatewayIp);
Instance->ServerIp = EFI_NTOHL (Override->ServerIp);
Instance->ListeningPort = Override->ServerPort;
Instance->MaxRetry = Override->TryCount;
Instance->Timeout = Override->TimeoutValue;
}
if (Instance->ListeningPort == 0) {
Instance->ListeningPort = MTFTP4_DEFAULT_SERVER_PORT;
}
if (Instance->MaxRetry == 0) {
Instance->MaxRetry = MTFTP4_DEFAULT_RETRY;
}
if (Instance->Timeout == 0) {
Instance->Timeout = MTFTP4_DEFAULT_TIMEOUT;
}
//
// Config the unicast UDP child to send initial request
//
Status = Mtftp4ConfigUnicastPort (Instance->UnicastPort, Instance);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
//
// Build and send an initial requests
//
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
if (Operation == EFI_MTFTP4_OPCODE_WRQ) {
Status = Mtftp4WrqStart (Instance, Operation);
} else {
Status = Mtftp4RrqStart (Instance, Operation);
}
NET_RESTORE_TPL (OldTpl);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
//
// Return immediately for asynchronous operation or poll the
// instance for synchronous operation.
//
Token->Status = EFI_NOT_READY;
if (Token->Event != NULL) {
return EFI_SUCCESS;
}
while (Token->Status == EFI_NOT_READY) {
This->Poll (This);
}
return Token->Status;
ON_ERROR:
Mtftp4CleanOperation (Instance, Status);
return Status;
}
STATIC
EFI_STATUS
EFIAPI
EfiMtftp4ReadFile (
IN EFI_MTFTP4_PROTOCOL *This,
IN EFI_MTFTP4_TOKEN *Token
)
/*++
Routine Description:
Read a file from the server.
Arguments:
This - The Mtftp protocol instance.
Token - The user's request wrap token.
Returns:
EFI_SUCCESS - The ReadFile has finished, the file has been downloaded
if it is synchronous operation, otherwise it has been
initated.
Others - Some error happened.
--*/
{
return Mtftp4Start (This, Token, EFI_MTFTP4_OPCODE_RRQ);
}
STATIC
EFI_STATUS
EFIAPI
EfiMtftp4WriteFile (
IN EFI_MTFTP4_PROTOCOL *This,
IN EFI_MTFTP4_TOKEN *Token
)
/*++
Routine Description:
Upload a file to the server.
Arguments:
This - The MTFTP protocol session
Token - The user's request wrap token.
Returns:
EFI_SUCCESS - The WriteFile has finished, the file has been uploaded
if it is synchronous operation, otherwise it has been
initated.
Others - Some error happened.
--*/
{
return Mtftp4Start (This, Token, EFI_MTFTP4_OPCODE_WRQ);
}
STATIC
EFI_STATUS
EFIAPI
EfiMtftp4ReadDirectory (
IN EFI_MTFTP4_PROTOCOL *This,
IN EFI_MTFTP4_TOKEN *Token
)
/*++
Routine Description:
Read a directory from the server. The only difference
between ReadFile and ReadDirectory is the opcode used.
Arguments:
This - The MTFTP protocol session
Token - The user's request wrap token.
Returns:
EFI_SUCCESS - The ReadDirectory has finished, the directory has been
downloaded as a file if it is synchronous operation,
otherwise it has been initated.
Others - Some error happened.
--*/
{
return Mtftp4Start (This, Token, EFI_MTFTP4_OPCODE_DIR);
}
STATIC
EFI_STATUS
EFIAPI
EfiMtftp4Poll (
IN EFI_MTFTP4_PROTOCOL *This
)
/*++
Routine Description:
Poll the network stack to accelerate the packet process.
Arguments:
This - The MTFTP protocol instance.
Returns:
EFI_INVALID_PARAMETER - This is NULL.
EFI_NOT_STARTED - The MTFTP session hasn't been configured.
EFI_DEVICE_ERROR - The MTFTP session has been destoried.
--*/
{
MTFTP4_PROTOCOL *Instance;
EFI_UDP4_PROTOCOL *Udp;
if (This == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = MTFTP4_PROTOCOL_FROM_THIS (This);
if (Instance->State == MTFTP4_STATE_UNCONFIGED) {
return EFI_NOT_STARTED;
} else if (Instance->State == MTFTP4_STATE_DESTORY) {
return EFI_DEVICE_ERROR;
}
Udp = Instance->UnicastPort->Udp;
return Udp->Poll (Udp);
}
EFI_MTFTP4_PROTOCOL gMtftp4ProtocolTemplate = {
EfiMtftp4GetModeData,
EfiMtftp4Configure,
EfiMtftp4GetInfo,
EfiMtftp4ParseOptions,
EfiMtftp4ReadFile,
EfiMtftp4WriteFile,
EfiMtftp4ReadDirectory,
EfiMtftp4Poll
};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?