123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179 |
- /** @file
- Functions implementation related with Mtftp for UefiPxeBc Driver.
- Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "PxeBcImpl.h"
- CHAR8 *mMtftpOptions[PXE_MTFTP_OPTION_MAXIMUM_INDEX] = {
- "blksize",
- "timeout",
- "tsize",
- "multicast",
- "windowsize"
- };
- /**
- This is a callback function when packets are received or transmitted in Mtftp driver.
- A callback function that is provided by the caller to intercept
- the EFI_MTFTP6_OPCODE_DATA or EFI_MTFTP6_OPCODE_DATA8 packets processed in the
- EFI_MTFTP6_PROTOCOL.ReadFile() function, and alternatively to intercept
- EFI_MTFTP6_OPCODE_OACK or EFI_MTFTP6_OPCODE_ERROR packets during a call to
- EFI_MTFTP6_PROTOCOL.ReadFile(), WriteFile() or ReadDirectory().
- @param[in] This Pointer to EFI_MTFTP6_PROTOCOL.
- @param[in] Token Pointer to EFI_MTFTP6_TOKEN.
- @param[in] PacketLen Length of EFI_MTFTP6_PACKET.
- @param[in] Packet Pointer to EFI_MTFTP6_PACKET to be checked.
- @retval EFI_SUCCESS The current operation succeeded.
- @retval EFI_ABORTED Abort the current transfer process.
- **/
- EFI_STATUS
- EFIAPI
- PxeBcMtftp6CheckPacket (
- IN EFI_MTFTP6_PROTOCOL *This,
- IN EFI_MTFTP6_TOKEN *Token,
- IN UINT16 PacketLen,
- IN EFI_MTFTP6_PACKET *Packet
- )
- {
- PXEBC_PRIVATE_DATA *Private;
- EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *Callback;
- EFI_STATUS Status;
- Private = (PXEBC_PRIVATE_DATA *)Token->Context;
- Callback = Private->PxeBcCallback;
- Status = EFI_SUCCESS;
- if (Packet->OpCode == EFI_MTFTP6_OPCODE_ERROR) {
- //
- // Store the tftp error message into mode data and set the received flag.
- //
- Private->Mode.TftpErrorReceived = TRUE;
- Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;
- AsciiStrnCpyS (
- Private->Mode.TftpError.ErrorString,
- PXE_MTFTP_ERROR_STRING_LENGTH,
- (CHAR8 *)Packet->Error.ErrorMessage,
- PXE_MTFTP_ERROR_STRING_LENGTH - 1
- );
- Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';
- }
- if (Callback != NULL) {
- //
- // Callback to user if has when received any tftp packet.
- //
- Status = Callback->Callback (
- Callback,
- Private->Function,
- TRUE,
- PacketLen,
- (EFI_PXE_BASE_CODE_PACKET *)Packet
- );
- if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {
- //
- // User wants to abort current process if not EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.
- //
- Status = EFI_ABORTED;
- } else {
- //
- // User wants to continue current process if EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.
- //
- Status = EFI_SUCCESS;
- }
- }
- return Status;
- }
- /**
- This function is to get the size of a file using Tftp.
- @param[in] Private Pointer to PxeBc private data.
- @param[in] Config Pointer to EFI_MTFTP6_CONFIG_DATA.
- @param[in] Filename Pointer to boot file name.
- @param[in] BlockSize Pointer to required block size.
- @param[in] WindowSize Pointer to required window size.
- @param[in, out] BufferSize Pointer to buffer size.
- @retval EFI_SUCCESS Successfully obtained the size of file.
- @retval EFI_NOT_FOUND Parse the tftp options failed.
- @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
- @retval Others Has not obtained the size of the file.
- **/
- EFI_STATUS
- PxeBcMtftp6GetFileSize (
- IN PXEBC_PRIVATE_DATA *Private,
- IN EFI_MTFTP6_CONFIG_DATA *Config,
- IN UINT8 *Filename,
- IN UINTN *BlockSize,
- IN UINTN *WindowSize,
- IN OUT UINT64 *BufferSize
- )
- {
- EFI_MTFTP6_PROTOCOL *Mtftp6;
- EFI_MTFTP6_OPTION ReqOpt[3];
- EFI_MTFTP6_PACKET *Packet;
- EFI_MTFTP6_OPTION *Option;
- UINT32 PktLen;
- UINT8 OptBuf[PXE_MTFTP_OPTBUF_MAXNUM_INDEX];
- UINTN OptBufSize;
- UINT32 OptCnt;
- EFI_STATUS Status;
- *BufferSize = 0;
- Status = EFI_DEVICE_ERROR;
- Mtftp6 = Private->Mtftp6;
- Packet = NULL;
- Option = NULL;
- PktLen = 0;
- OptBufSize = PXE_MTFTP_OPTBUF_MAXNUM_INDEX;
- OptCnt = 1;
- Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
- Status = Mtftp6->Configure (Mtftp6, Config);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Build the required options for get info.
- //
- ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];
- PxeBcUintnToAscDec (0, OptBuf, OptBufSize);
- ReqOpt[0].ValueStr = OptBuf;
- if (BlockSize != NULL) {
- ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
- ReqOpt[OptCnt].ValueStr = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
- OptBufSize -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
- PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, OptBufSize);
- OptCnt++;
- }
- if (WindowSize != NULL) {
- ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
- ReqOpt[OptCnt].ValueStr = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
- OptBufSize -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
- PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, OptBufSize);
- OptCnt++;
- }
- Status = Mtftp6->GetInfo (
- Mtftp6,
- NULL,
- Filename,
- NULL,
- (UINT8)OptCnt,
- ReqOpt,
- &PktLen,
- &Packet
- );
- if (EFI_ERROR (Status)) {
- if (Status == EFI_TFTP_ERROR) {
- //
- // Store the tftp error message into mode data and set the received flag.
- //
- Private->Mode.TftpErrorReceived = TRUE;
- Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;
- AsciiStrnCpyS (
- Private->Mode.TftpError.ErrorString,
- PXE_MTFTP_ERROR_STRING_LENGTH,
- (CHAR8 *)Packet->Error.ErrorMessage,
- PXE_MTFTP_ERROR_STRING_LENGTH - 1
- );
- Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';
- }
- goto ON_ERROR;
- }
- //
- // Parse the options in the reply packet.
- //
- OptCnt = 0;
- Status = Mtftp6->ParseOptions (
- Mtftp6,
- PktLen,
- Packet,
- (UINT32 *)&OptCnt,
- &Option
- );
- if (EFI_ERROR (Status)) {
- goto ON_ERROR;
- }
- //
- // Parse out the value of "tsize" option.
- //
- Status = EFI_NOT_FOUND;
- while (OptCnt != 0) {
- if (AsciiStrnCmp ((CHAR8 *)Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {
- *BufferSize = AsciiStrDecimalToUint64 ((CHAR8 *)(Option[OptCnt - 1].ValueStr));
- Status = EFI_SUCCESS;
- }
- OptCnt--;
- }
- FreePool (Option);
- ON_ERROR:
- if (Packet != NULL) {
- FreePool (Packet);
- }
- Mtftp6->Configure (Mtftp6, NULL);
- return Status;
- }
- /**
- This function is to get data of a file using Tftp.
- @param[in] Private Pointer to PxeBc private data.
- @param[in] Config Pointer to EFI_MTFTP6_CONFIG_DATA.
- @param[in] Filename Pointer to boot file name.
- @param[in] BlockSize Pointer to required block size.
- @param[in] WindowSize Pointer to required window size.
- @param[in] BufferPtr Pointer to buffer.
- @param[in, out] BufferSize Pointer to buffer size.
- @param[in] DontUseBuffer Indicates whether with a receive buffer.
- @retval EFI_SUCCESS Successfully read the data from the special file.
- @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
- @retval Others Read data from file failed.
- **/
- EFI_STATUS
- PxeBcMtftp6ReadFile (
- IN PXEBC_PRIVATE_DATA *Private,
- IN EFI_MTFTP6_CONFIG_DATA *Config,
- IN UINT8 *Filename,
- IN UINTN *BlockSize,
- IN UINTN *WindowSize,
- IN UINT8 *BufferPtr,
- IN OUT UINT64 *BufferSize,
- IN BOOLEAN DontUseBuffer
- )
- {
- EFI_MTFTP6_PROTOCOL *Mtftp6;
- EFI_MTFTP6_TOKEN Token;
- EFI_MTFTP6_OPTION ReqOpt[2];
- UINT32 OptCnt;
- UINT8 BlksizeBuf[10];
- UINT8 WindowsizeBuf[10];
- EFI_STATUS Status;
- Status = EFI_DEVICE_ERROR;
- Mtftp6 = Private->Mtftp6;
- OptCnt = 0;
- Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
- Status = Mtftp6->Configure (Mtftp6, Config);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if (BlockSize != NULL) {
- ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
- ReqOpt[OptCnt].ValueStr = BlksizeBuf;
- PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));
- OptCnt++;
- }
- if (WindowSize != NULL) {
- ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
- ReqOpt[OptCnt].ValueStr = WindowsizeBuf;
- PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));
- OptCnt++;
- }
- Token.Event = NULL;
- Token.OverrideData = NULL;
- Token.Filename = Filename;
- Token.ModeStr = NULL;
- Token.OptionCount = OptCnt;
- Token.OptionList = ReqOpt;
- Token.Context = Private;
- if (DontUseBuffer) {
- Token.BufferSize = 0;
- Token.Buffer = NULL;
- } else {
- Token.BufferSize = *BufferSize;
- Token.Buffer = BufferPtr;
- }
- Token.CheckPacket = PxeBcMtftp6CheckPacket;
- Token.TimeoutCallback = NULL;
- Token.PacketNeeded = NULL;
- Status = Mtftp6->ReadFile (Mtftp6, &Token);
- //
- // Get the real size of received buffer.
- //
- *BufferSize = Token.BufferSize;
- Mtftp6->Configure (Mtftp6, NULL);
- return Status;
- }
- /**
- This function is used to write the data of a file using Tftp.
- @param[in] Private Pointer to PxeBc private data.
- @param[in] Config Pointer to EFI_MTFTP6_CONFIG_DATA.
- @param[in] Filename Pointer to boot file name.
- @param[in] Overwrite Indicate whether with overwrite attribute.
- @param[in] BlockSize Pointer to required block size.
- @param[in] BufferPtr Pointer to buffer.
- @param[in, out] BufferSize Pointer to buffer size.
- @retval EFI_SUCCESS Successfully wrote the data into a special file.
- @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
- @retval other Write data into file failed.
- **/
- EFI_STATUS
- PxeBcMtftp6WriteFile (
- IN PXEBC_PRIVATE_DATA *Private,
- IN EFI_MTFTP6_CONFIG_DATA *Config,
- IN UINT8 *Filename,
- IN BOOLEAN Overwrite,
- IN UINTN *BlockSize,
- IN UINT8 *BufferPtr,
- IN OUT UINT64 *BufferSize
- )
- {
- EFI_MTFTP6_PROTOCOL *Mtftp6;
- EFI_MTFTP6_TOKEN Token;
- EFI_MTFTP6_OPTION ReqOpt[1];
- UINT32 OptCnt;
- UINT8 OptBuf[128];
- EFI_STATUS Status;
- Status = EFI_DEVICE_ERROR;
- Mtftp6 = Private->Mtftp6;
- OptCnt = 0;
- Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
- Status = Mtftp6->Configure (Mtftp6, Config);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if (BlockSize != NULL) {
- ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
- ReqOpt[0].ValueStr = OptBuf;
- PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr, PXE_MTFTP_OPTBUF_MAXNUM_INDEX);
- OptCnt++;
- }
- Token.Event = NULL;
- Token.OverrideData = NULL;
- Token.Filename = Filename;
- Token.ModeStr = NULL;
- Token.OptionCount = OptCnt;
- Token.OptionList = ReqOpt;
- Token.BufferSize = *BufferSize;
- Token.Buffer = BufferPtr;
- Token.CheckPacket = PxeBcMtftp6CheckPacket;
- Token.TimeoutCallback = NULL;
- Token.PacketNeeded = NULL;
- Status = Mtftp6->WriteFile (Mtftp6, &Token);
- //
- // Get the real size of transmitted buffer.
- //
- *BufferSize = Token.BufferSize;
- Mtftp6->Configure (Mtftp6, NULL);
- return Status;
- }
- /**
- This function is to read the data (file) from a directory using Tftp.
- @param[in] Private Pointer to PxeBc private data.
- @param[in] Config Pointer to EFI_MTFTP6_CONFIG_DATA.
- @param[in] Filename Pointer to boot file name.
- @param[in] BlockSize Pointer to required block size.
- @param[in] WindowSize Pointer to required window size.
- @param[in] BufferPtr Pointer to buffer.
- @param[in, out] BufferSize Pointer to buffer size.
- @param[in] DontUseBuffer Indicates whether to use a receive buffer.
- @retval EFI_SUCCESS Successfully obtained the data from the file included in directory.
- @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
- @retval Others Operation failed.
- **/
- EFI_STATUS
- PxeBcMtftp6ReadDirectory (
- IN PXEBC_PRIVATE_DATA *Private,
- IN EFI_MTFTP6_CONFIG_DATA *Config,
- IN UINT8 *Filename,
- IN UINTN *BlockSize,
- IN UINTN *WindowSize,
- IN UINT8 *BufferPtr,
- IN OUT UINT64 *BufferSize,
- IN BOOLEAN DontUseBuffer
- )
- {
- EFI_MTFTP6_PROTOCOL *Mtftp6;
- EFI_MTFTP6_TOKEN Token;
- EFI_MTFTP6_OPTION ReqOpt[2];
- UINT32 OptCnt;
- UINT8 BlksizeBuf[10];
- UINT8 WindowsizeBuf[10];
- EFI_STATUS Status;
- Status = EFI_DEVICE_ERROR;
- Mtftp6 = Private->Mtftp6;
- OptCnt = 0;
- Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
- Status = Mtftp6->Configure (Mtftp6, Config);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if (BlockSize != NULL) {
- ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
- ReqOpt[OptCnt].ValueStr = BlksizeBuf;
- PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));
- OptCnt++;
- }
- if (WindowSize != NULL) {
- ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
- ReqOpt[OptCnt].ValueStr = WindowsizeBuf;
- PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));
- OptCnt++;
- }
- Token.Event = NULL;
- Token.OverrideData = NULL;
- Token.Filename = Filename;
- Token.ModeStr = NULL;
- Token.OptionCount = OptCnt;
- Token.OptionList = ReqOpt;
- Token.Context = Private;
- if (DontUseBuffer) {
- Token.BufferSize = 0;
- Token.Buffer = NULL;
- } else {
- Token.BufferSize = *BufferSize;
- Token.Buffer = BufferPtr;
- }
- Token.CheckPacket = PxeBcMtftp6CheckPacket;
- Token.TimeoutCallback = NULL;
- Token.PacketNeeded = NULL;
- Status = Mtftp6->ReadDirectory (Mtftp6, &Token);
- //
- // Get the real size of received buffer.
- //
- *BufferSize = Token.BufferSize;
- Mtftp6->Configure (Mtftp6, NULL);
- return Status;
- }
- /**
- This is a callback function when packets are received or transmitted in Mtftp driver.
- A callback function that is provided by the caller to intercept
- the EFI_MTFTP6_OPCODE_DATA or EFI_MTFTP4_OPCODE_DATA8 packets processed in the
- EFI_MTFTP4_PROTOCOL.ReadFile() function, and alternatively to intercept
- EFI_MTFTP4_OPCODE_OACK or EFI_MTFTP4_OPCODE_ERROR packets during a call to
- EFI_MTFTP4_PROTOCOL.ReadFile(), WriteFile() or ReadDirectory().
- @param[in] This Pointer to EFI_MTFTP4_PROTOCOL.
- @param[in] Token Pointer to EFI_MTFTP4_TOKEN.
- @param[in] PacketLen Length of EFI_MTFTP4_PACKET.
- @param[in] Packet Pointer to EFI_MTFTP4_PACKET to be checked.
- @retval EFI_SUCCESS The current operation succeeded.
- @retval EFI_ABORTED Abort the current transfer process.
- **/
- EFI_STATUS
- EFIAPI
- PxeBcMtftp4CheckPacket (
- IN EFI_MTFTP4_PROTOCOL *This,
- IN EFI_MTFTP4_TOKEN *Token,
- IN UINT16 PacketLen,
- IN EFI_MTFTP4_PACKET *Packet
- )
- {
- PXEBC_PRIVATE_DATA *Private;
- EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *Callback;
- EFI_STATUS Status;
- Private = (PXEBC_PRIVATE_DATA *)Token->Context;
- Callback = Private->PxeBcCallback;
- Status = EFI_SUCCESS;
- if (Packet->OpCode == EFI_MTFTP4_OPCODE_ERROR) {
- //
- // Store the tftp error message into mode data and set the received flag.
- //
- Private->Mode.TftpErrorReceived = TRUE;
- Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;
- AsciiStrnCpyS (
- Private->Mode.TftpError.ErrorString,
- PXE_MTFTP_ERROR_STRING_LENGTH,
- (CHAR8 *)Packet->Error.ErrorMessage,
- PXE_MTFTP_ERROR_STRING_LENGTH - 1
- );
- Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';
- }
- if (Callback != NULL) {
- //
- // Callback to user if has when received any tftp packet.
- //
- Status = Callback->Callback (
- Callback,
- Private->Function,
- TRUE,
- PacketLen,
- (EFI_PXE_BASE_CODE_PACKET *)Packet
- );
- if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {
- //
- // User wants to abort current process if not EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.
- //
- Status = EFI_ABORTED;
- } else {
- //
- // User wants to continue current process if EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.
- //
- Status = EFI_SUCCESS;
- }
- }
- return Status;
- }
- /**
- This function is to get size of a file using Tftp.
- @param[in] Private Pointer to PxeBc private data.
- @param[in] Config Pointer to EFI_MTFTP4_CONFIG_DATA.
- @param[in] Filename Pointer to boot file name.
- @param[in] BlockSize Pointer to required block size.
- @param[in] WindowSize Pointer to required window size.
- @param[in, out] BufferSize Pointer to buffer size.
- @retval EFI_SUCCESS Successfully obtained the size of file.
- @retval EFI_NOT_FOUND Parse the tftp options failed.
- @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
- @retval Others Did not obtain the size of the file.
- **/
- EFI_STATUS
- PxeBcMtftp4GetFileSize (
- IN PXEBC_PRIVATE_DATA *Private,
- IN EFI_MTFTP4_CONFIG_DATA *Config,
- IN UINT8 *Filename,
- IN UINTN *BlockSize,
- IN UINTN *WindowSize,
- IN OUT UINT64 *BufferSize
- )
- {
- EFI_MTFTP4_PROTOCOL *Mtftp4;
- EFI_MTFTP4_OPTION ReqOpt[3];
- EFI_MTFTP4_PACKET *Packet;
- EFI_MTFTP4_OPTION *Option;
- UINT32 PktLen;
- UINT8 OptBuf[PXE_MTFTP_OPTBUF_MAXNUM_INDEX];
- UINTN OptBufSize;
- UINT32 OptCnt;
- EFI_STATUS Status;
- *BufferSize = 0;
- Status = EFI_DEVICE_ERROR;
- Mtftp4 = Private->Mtftp4;
- Packet = NULL;
- Option = NULL;
- PktLen = 0;
- OptBufSize = PXE_MTFTP_OPTBUF_MAXNUM_INDEX;
- OptCnt = 1;
- Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
- Status = Mtftp4->Configure (Mtftp4, Config);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Build the required options for get info.
- //
- ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];
- PxeBcUintnToAscDec (0, OptBuf, OptBufSize);
- ReqOpt[0].ValueStr = OptBuf;
- if (BlockSize != NULL) {
- ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
- ReqOpt[OptCnt].ValueStr = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
- OptBufSize -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
- PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, OptBufSize);
- OptCnt++;
- }
- if (WindowSize != NULL) {
- ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
- ReqOpt[OptCnt].ValueStr = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
- OptBufSize -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
- PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, OptBufSize);
- OptCnt++;
- }
- Status = Mtftp4->GetInfo (
- Mtftp4,
- NULL,
- Filename,
- NULL,
- (UINT8)OptCnt,
- ReqOpt,
- &PktLen,
- &Packet
- );
- if (EFI_ERROR (Status)) {
- if (Status == EFI_TFTP_ERROR) {
- //
- // Store the tftp error message into mode data and set the received flag.
- //
- Private->Mode.TftpErrorReceived = TRUE;
- Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;
- AsciiStrnCpyS (
- Private->Mode.TftpError.ErrorString,
- PXE_MTFTP_ERROR_STRING_LENGTH,
- (CHAR8 *)Packet->Error.ErrorMessage,
- PXE_MTFTP_ERROR_STRING_LENGTH - 1
- );
- Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';
- }
- goto ON_ERROR;
- }
- //
- // Parse the options in the reply packet.
- //
- OptCnt = 0;
- Status = Mtftp4->ParseOptions (
- Mtftp4,
- PktLen,
- Packet,
- (UINT32 *)&OptCnt,
- &Option
- );
- if (EFI_ERROR (Status)) {
- goto ON_ERROR;
- }
- //
- // Parse out the value of "tsize" option.
- //
- Status = EFI_NOT_FOUND;
- while (OptCnt != 0) {
- if (AsciiStrnCmp ((CHAR8 *)Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {
- *BufferSize = AsciiStrDecimalToUint64 ((CHAR8 *)(Option[OptCnt - 1].ValueStr));
- Status = EFI_SUCCESS;
- }
- OptCnt--;
- }
- FreePool (Option);
- ON_ERROR:
- if (Packet != NULL) {
- FreePool (Packet);
- }
- Mtftp4->Configure (Mtftp4, NULL);
- return Status;
- }
- /**
- This function is to read the data of a file using Tftp.
- @param[in] Private Pointer to PxeBc private data.
- @param[in] Config Pointer to EFI_MTFTP4_CONFIG_DATA.
- @param[in] Filename Pointer to boot file name.
- @param[in] BlockSize Pointer to required block size.
- @param[in] WindowSize Pointer to required window size.
- @param[in] BufferPtr Pointer to buffer.
- @param[in, out] BufferSize Pointer to buffer size.
- @param[in] DontUseBuffer Indicates whether to use a receive buffer.
- @retval EFI_SUCCESS Successfully read the data from the special file.
- @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
- @retval Others Read data from file failed.
- **/
- EFI_STATUS
- PxeBcMtftp4ReadFile (
- IN PXEBC_PRIVATE_DATA *Private,
- IN EFI_MTFTP4_CONFIG_DATA *Config,
- IN UINT8 *Filename,
- IN UINTN *BlockSize,
- IN UINTN *WindowSize,
- IN UINT8 *BufferPtr,
- IN OUT UINT64 *BufferSize,
- IN BOOLEAN DontUseBuffer
- )
- {
- EFI_MTFTP4_PROTOCOL *Mtftp4;
- EFI_MTFTP4_TOKEN Token;
- EFI_MTFTP4_OPTION ReqOpt[2];
- UINT32 OptCnt;
- UINT8 BlksizeBuf[10];
- UINT8 WindowsizeBuf[10];
- EFI_STATUS Status;
- Status = EFI_DEVICE_ERROR;
- Mtftp4 = Private->Mtftp4;
- OptCnt = 0;
- Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
- Status = Mtftp4->Configure (Mtftp4, Config);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if (BlockSize != NULL) {
- ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
- ReqOpt[OptCnt].ValueStr = BlksizeBuf;
- PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));
- OptCnt++;
- }
- if (WindowSize != NULL) {
- ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
- ReqOpt[OptCnt].ValueStr = WindowsizeBuf;
- PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));
- OptCnt++;
- }
- Token.Event = NULL;
- Token.OverrideData = NULL;
- Token.Filename = Filename;
- Token.ModeStr = NULL;
- Token.OptionCount = OptCnt;
- Token.OptionList = ReqOpt;
- Token.Context = Private;
- if (DontUseBuffer) {
- Token.BufferSize = 0;
- Token.Buffer = NULL;
- } else {
- Token.BufferSize = *BufferSize;
- Token.Buffer = BufferPtr;
- }
- Token.CheckPacket = PxeBcMtftp4CheckPacket;
- Token.TimeoutCallback = NULL;
- Token.PacketNeeded = NULL;
- Status = Mtftp4->ReadFile (Mtftp4, &Token);
- //
- // Get the real size of received buffer.
- //
- *BufferSize = Token.BufferSize;
- Mtftp4->Configure (Mtftp4, NULL);
- return Status;
- }
- /**
- This function is to write the data of a file using Tftp.
- @param[in] Private Pointer to PxeBc private data.
- @param[in] Config Pointer to EFI_MTFTP4_CONFIG_DATA.
- @param[in] Filename Pointer to boot file name.
- @param[in] Overwrite Indicates whether to use the overwrite attribute.
- @param[in] BlockSize Pointer to required block size.
- @param[in] BufferPtr Pointer to buffer.
- @param[in, out] BufferSize Pointer to buffer size.
- @retval EFI_SUCCESS Successfully write the data into the special file.
- @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
- @retval other Write data into file failed.
- **/
- EFI_STATUS
- PxeBcMtftp4WriteFile (
- IN PXEBC_PRIVATE_DATA *Private,
- IN EFI_MTFTP4_CONFIG_DATA *Config,
- IN UINT8 *Filename,
- IN BOOLEAN Overwrite,
- IN UINTN *BlockSize,
- IN UINT8 *BufferPtr,
- IN OUT UINT64 *BufferSize
- )
- {
- EFI_MTFTP4_PROTOCOL *Mtftp4;
- EFI_MTFTP4_TOKEN Token;
- EFI_MTFTP4_OPTION ReqOpt[1];
- UINT32 OptCnt;
- UINT8 OptBuf[128];
- EFI_STATUS Status;
- Status = EFI_DEVICE_ERROR;
- Mtftp4 = Private->Mtftp4;
- OptCnt = 0;
- Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
- Status = Mtftp4->Configure (Mtftp4, Config);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if (BlockSize != NULL) {
- ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
- ReqOpt[0].ValueStr = OptBuf;
- PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr, PXE_MTFTP_OPTBUF_MAXNUM_INDEX);
- OptCnt++;
- }
- Token.Event = NULL;
- Token.OverrideData = NULL;
- Token.Filename = Filename;
- Token.ModeStr = NULL;
- Token.OptionCount = OptCnt;
- Token.OptionList = ReqOpt;
- Token.BufferSize = *BufferSize;
- Token.Buffer = BufferPtr;
- Token.CheckPacket = PxeBcMtftp4CheckPacket;
- Token.TimeoutCallback = NULL;
- Token.PacketNeeded = NULL;
- Status = Mtftp4->WriteFile (Mtftp4, &Token);
- //
- // Get the real size of transmitted buffer.
- //
- *BufferSize = Token.BufferSize;
- Mtftp4->Configure (Mtftp4, NULL);
- return Status;
- }
- /**
- This function is to get data (file) from a directory using Tftp.
- @param[in] Private Pointer to PxeBc private data.
- @param[in] Config Pointer to EFI_MTFTP4_CONFIG_DATA.
- @param[in] Filename Pointer to boot file name.
- @param[in] BlockSize Pointer to required block size.
- @param[in] WindowSize Pointer to required window size.
- @param[in] BufferPtr Pointer to buffer.
- @param[in, out] BufferSize Pointer to buffer size.
- @param[in] DontUseBuffer Indicates whether to use a receive buffer.
- @retval EFI_SUCCESS Successfully obtained the data from the file included in the directory.
- @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
- @retval Others Operation failed.
- **/
- EFI_STATUS
- PxeBcMtftp4ReadDirectory (
- IN PXEBC_PRIVATE_DATA *Private,
- IN EFI_MTFTP4_CONFIG_DATA *Config,
- IN UINT8 *Filename,
- IN UINTN *BlockSize,
- IN UINTN *WindowSize,
- IN UINT8 *BufferPtr,
- IN OUT UINT64 *BufferSize,
- IN BOOLEAN DontUseBuffer
- )
- {
- EFI_MTFTP4_PROTOCOL *Mtftp4;
- EFI_MTFTP4_TOKEN Token;
- EFI_MTFTP4_OPTION ReqOpt[2];
- UINT32 OptCnt;
- UINT8 BlksizeBuf[10];
- UINT8 WindowsizeBuf[10];
- EFI_STATUS Status;
- Status = EFI_DEVICE_ERROR;
- Mtftp4 = Private->Mtftp4;
- OptCnt = 0;
- Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
- Status = Mtftp4->Configure (Mtftp4, Config);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if (BlockSize != NULL) {
- ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
- ReqOpt[OptCnt].ValueStr = BlksizeBuf;
- PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));
- OptCnt++;
- }
- if (WindowSize != NULL) {
- ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
- ReqOpt[OptCnt].ValueStr = WindowsizeBuf;
- PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));
- OptCnt++;
- }
- Token.Event = NULL;
- Token.OverrideData = NULL;
- Token.Filename = Filename;
- Token.ModeStr = NULL;
- Token.OptionCount = OptCnt;
- Token.OptionList = ReqOpt;
- Token.Context = Private;
- if (DontUseBuffer) {
- Token.BufferSize = 0;
- Token.Buffer = NULL;
- } else {
- Token.BufferSize = *BufferSize;
- Token.Buffer = BufferPtr;
- }
- Token.CheckPacket = PxeBcMtftp4CheckPacket;
- Token.TimeoutCallback = NULL;
- Token.PacketNeeded = NULL;
- Status = Mtftp4->ReadDirectory (Mtftp4, &Token);
- //
- // Get the real size of received buffer.
- //
- *BufferSize = Token.BufferSize;
- Mtftp4->Configure (Mtftp4, NULL);
- return Status;
- }
- /**
- This function is wrapper to get the file size using TFTP.
- @param[in] Private Pointer to PxeBc private data.
- @param[in] Config Pointer to configure data.
- @param[in] Filename Pointer to boot file name.
- @param[in] BlockSize Pointer to required block size.
- @param[in] WindowSize Pointer to required window size.
- @param[in, out] BufferSize Pointer to buffer size.
- @retval EFI_SUCCESS Successfully obtained the size of file.
- @retval EFI_NOT_FOUND Parse the tftp options failed.
- @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
- @retval Others Did not obtain the size of the file.
- **/
- EFI_STATUS
- PxeBcTftpGetFileSize (
- IN PXEBC_PRIVATE_DATA *Private,
- IN VOID *Config,
- IN UINT8 *Filename,
- IN UINTN *BlockSize,
- IN UINTN *WindowSize,
- IN OUT UINT64 *BufferSize
- )
- {
- if (Private->PxeBc.Mode->UsingIpv6) {
- return PxeBcMtftp6GetFileSize (
- Private,
- (EFI_MTFTP6_CONFIG_DATA *)Config,
- Filename,
- BlockSize,
- WindowSize,
- BufferSize
- );
- } else {
- return PxeBcMtftp4GetFileSize (
- Private,
- (EFI_MTFTP4_CONFIG_DATA *)Config,
- Filename,
- BlockSize,
- WindowSize,
- BufferSize
- );
- }
- }
- /**
- This function is a wrapper to get file using TFTP.
- @param[in] Private Pointer to PxeBc private data.
- @param[in] Config Pointer to config data.
- @param[in] Filename Pointer to boot file name.
- @param[in] BlockSize Pointer to required block size.
- @param[in] WindowSize Pointer to required window size.
- @param[in] BufferPtr Pointer to buffer.
- @param[in, out] BufferSize Pointer to buffer size.
- @param[in] DontUseBuffer Indicates whether to use a receive buffer.
- @retval EFI_SUCCESS Successfully read the data from the special file.
- @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
- @retval Others Read data from file failed.
- **/
- EFI_STATUS
- PxeBcTftpReadFile (
- IN PXEBC_PRIVATE_DATA *Private,
- IN VOID *Config,
- IN UINT8 *Filename,
- IN UINTN *BlockSize,
- IN UINTN *WindowSize,
- IN UINT8 *BufferPtr,
- IN OUT UINT64 *BufferSize,
- IN BOOLEAN DontUseBuffer
- )
- {
- if (Private->PxeBc.Mode->UsingIpv6) {
- return PxeBcMtftp6ReadFile (
- Private,
- (EFI_MTFTP6_CONFIG_DATA *)Config,
- Filename,
- BlockSize,
- WindowSize,
- BufferPtr,
- BufferSize,
- DontUseBuffer
- );
- } else {
- return PxeBcMtftp4ReadFile (
- Private,
- (EFI_MTFTP4_CONFIG_DATA *)Config,
- Filename,
- BlockSize,
- WindowSize,
- BufferPtr,
- BufferSize,
- DontUseBuffer
- );
- }
- }
- /**
- This function is a wrapper to write file using TFTP.
- @param[in] Private Pointer to PxeBc private data.
- @param[in] Config Pointer to config data.
- @param[in] Filename Pointer to boot file name.
- @param[in] Overwrite Indicate whether with overwrite attribute.
- @param[in] BlockSize Pointer to required block size.
- @param[in] BufferPtr Pointer to buffer.
- @param[in, out] BufferSize Pointer to buffer size.
- @retval EFI_SUCCESS Successfully wrote the data into a special file.
- @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
- @retval other Write data into file failed.
- **/
- EFI_STATUS
- PxeBcTftpWriteFile (
- IN PXEBC_PRIVATE_DATA *Private,
- IN VOID *Config,
- IN UINT8 *Filename,
- IN BOOLEAN Overwrite,
- IN UINTN *BlockSize,
- IN UINT8 *BufferPtr,
- IN OUT UINT64 *BufferSize
- )
- {
- if (Private->PxeBc.Mode->UsingIpv6) {
- return PxeBcMtftp6WriteFile (
- Private,
- (EFI_MTFTP6_CONFIG_DATA *)Config,
- Filename,
- Overwrite,
- BlockSize,
- BufferPtr,
- BufferSize
- );
- } else {
- return PxeBcMtftp4WriteFile (
- Private,
- (EFI_MTFTP4_CONFIG_DATA *)Config,
- Filename,
- Overwrite,
- BlockSize,
- BufferPtr,
- BufferSize
- );
- }
- }
- /**
- This function is a wrapper to get the data (file) from a directory using TFTP.
- @param[in] Private Pointer to PxeBc private data.
- @param[in] Config Pointer to config data.
- @param[in] Filename Pointer to boot file name.
- @param[in] BlockSize Pointer to required block size.
- @param[in] WindowSize Pointer to required window size.
- @param[in] BufferPtr Pointer to buffer.
- @param[in, out] BufferSize Pointer to buffer size.
- @param[in] DontUseBuffer Indicatse whether to use a receive buffer.
- @retval EFI_SUCCESS Successfully obtained the data from the file included in the directory.
- @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
- @retval Others Operation failed.
- **/
- EFI_STATUS
- PxeBcTftpReadDirectory (
- IN PXEBC_PRIVATE_DATA *Private,
- IN VOID *Config,
- IN UINT8 *Filename,
- IN UINTN *BlockSize,
- IN UINTN *WindowSize,
- IN UINT8 *BufferPtr,
- IN OUT UINT64 *BufferSize,
- IN BOOLEAN DontUseBuffer
- )
- {
- if (Private->PxeBc.Mode->UsingIpv6) {
- return PxeBcMtftp6ReadDirectory (
- Private,
- (EFI_MTFTP6_CONFIG_DATA *)Config,
- Filename,
- BlockSize,
- WindowSize,
- BufferPtr,
- BufferSize,
- DontUseBuffer
- );
- } else {
- return PxeBcMtftp4ReadDirectory (
- Private,
- (EFI_MTFTP4_CONFIG_DATA *)Config,
- Filename,
- BlockSize,
- WindowSize,
- BufferPtr,
- BufferSize,
- DontUseBuffer
- );
- }
- }
|