PxeBcMtftp.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179
  1. /** @file
  2. Functions implementation related with Mtftp for UefiPxeBc Driver.
  3. Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "PxeBcImpl.h"
  7. CHAR8 *mMtftpOptions[PXE_MTFTP_OPTION_MAXIMUM_INDEX] = {
  8. "blksize",
  9. "timeout",
  10. "tsize",
  11. "multicast",
  12. "windowsize"
  13. };
  14. /**
  15. This is a callback function when packets are received or transmitted in Mtftp driver.
  16. A callback function that is provided by the caller to intercept
  17. the EFI_MTFTP6_OPCODE_DATA or EFI_MTFTP6_OPCODE_DATA8 packets processed in the
  18. EFI_MTFTP6_PROTOCOL.ReadFile() function, and alternatively to intercept
  19. EFI_MTFTP6_OPCODE_OACK or EFI_MTFTP6_OPCODE_ERROR packets during a call to
  20. EFI_MTFTP6_PROTOCOL.ReadFile(), WriteFile() or ReadDirectory().
  21. @param[in] This Pointer to EFI_MTFTP6_PROTOCOL.
  22. @param[in] Token Pointer to EFI_MTFTP6_TOKEN.
  23. @param[in] PacketLen Length of EFI_MTFTP6_PACKET.
  24. @param[in] Packet Pointer to EFI_MTFTP6_PACKET to be checked.
  25. @retval EFI_SUCCESS The current operation succeeded.
  26. @retval EFI_ABORTED Abort the current transfer process.
  27. **/
  28. EFI_STATUS
  29. EFIAPI
  30. PxeBcMtftp6CheckPacket (
  31. IN EFI_MTFTP6_PROTOCOL *This,
  32. IN EFI_MTFTP6_TOKEN *Token,
  33. IN UINT16 PacketLen,
  34. IN EFI_MTFTP6_PACKET *Packet
  35. )
  36. {
  37. PXEBC_PRIVATE_DATA *Private;
  38. EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *Callback;
  39. EFI_STATUS Status;
  40. Private = (PXEBC_PRIVATE_DATA *)Token->Context;
  41. Callback = Private->PxeBcCallback;
  42. Status = EFI_SUCCESS;
  43. if (Packet->OpCode == EFI_MTFTP6_OPCODE_ERROR) {
  44. //
  45. // Store the tftp error message into mode data and set the received flag.
  46. //
  47. Private->Mode.TftpErrorReceived = TRUE;
  48. Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;
  49. AsciiStrnCpyS (
  50. Private->Mode.TftpError.ErrorString,
  51. PXE_MTFTP_ERROR_STRING_LENGTH,
  52. (CHAR8 *)Packet->Error.ErrorMessage,
  53. PXE_MTFTP_ERROR_STRING_LENGTH - 1
  54. );
  55. Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';
  56. }
  57. if (Callback != NULL) {
  58. //
  59. // Callback to user if has when received any tftp packet.
  60. //
  61. Status = Callback->Callback (
  62. Callback,
  63. Private->Function,
  64. TRUE,
  65. PacketLen,
  66. (EFI_PXE_BASE_CODE_PACKET *)Packet
  67. );
  68. if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {
  69. //
  70. // User wants to abort current process if not EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.
  71. //
  72. Status = EFI_ABORTED;
  73. } else {
  74. //
  75. // User wants to continue current process if EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.
  76. //
  77. Status = EFI_SUCCESS;
  78. }
  79. }
  80. return Status;
  81. }
  82. /**
  83. This function is to get the size of a file using Tftp.
  84. @param[in] Private Pointer to PxeBc private data.
  85. @param[in] Config Pointer to EFI_MTFTP6_CONFIG_DATA.
  86. @param[in] Filename Pointer to boot file name.
  87. @param[in] BlockSize Pointer to required block size.
  88. @param[in] WindowSize Pointer to required window size.
  89. @param[in, out] BufferSize Pointer to buffer size.
  90. @retval EFI_SUCCESS Successfully obtained the size of file.
  91. @retval EFI_NOT_FOUND Parse the tftp options failed.
  92. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
  93. @retval Others Has not obtained the size of the file.
  94. **/
  95. EFI_STATUS
  96. PxeBcMtftp6GetFileSize (
  97. IN PXEBC_PRIVATE_DATA *Private,
  98. IN EFI_MTFTP6_CONFIG_DATA *Config,
  99. IN UINT8 *Filename,
  100. IN UINTN *BlockSize,
  101. IN UINTN *WindowSize,
  102. IN OUT UINT64 *BufferSize
  103. )
  104. {
  105. EFI_MTFTP6_PROTOCOL *Mtftp6;
  106. EFI_MTFTP6_OPTION ReqOpt[3];
  107. EFI_MTFTP6_PACKET *Packet;
  108. EFI_MTFTP6_OPTION *Option;
  109. UINT32 PktLen;
  110. UINT8 OptBuf[PXE_MTFTP_OPTBUF_MAXNUM_INDEX];
  111. UINTN OptBufSize;
  112. UINT32 OptCnt;
  113. EFI_STATUS Status;
  114. *BufferSize = 0;
  115. Status = EFI_DEVICE_ERROR;
  116. Mtftp6 = Private->Mtftp6;
  117. Packet = NULL;
  118. Option = NULL;
  119. PktLen = 0;
  120. OptBufSize = PXE_MTFTP_OPTBUF_MAXNUM_INDEX;
  121. OptCnt = 1;
  122. Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
  123. Status = Mtftp6->Configure (Mtftp6, Config);
  124. if (EFI_ERROR (Status)) {
  125. return Status;
  126. }
  127. //
  128. // Build the required options for get info.
  129. //
  130. ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];
  131. PxeBcUintnToAscDec (0, OptBuf, OptBufSize);
  132. ReqOpt[0].ValueStr = OptBuf;
  133. if (BlockSize != NULL) {
  134. ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
  135. ReqOpt[OptCnt].ValueStr = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
  136. OptBufSize -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
  137. PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, OptBufSize);
  138. OptCnt++;
  139. }
  140. if (WindowSize != NULL) {
  141. ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
  142. ReqOpt[OptCnt].ValueStr = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
  143. OptBufSize -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
  144. PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, OptBufSize);
  145. OptCnt++;
  146. }
  147. Status = Mtftp6->GetInfo (
  148. Mtftp6,
  149. NULL,
  150. Filename,
  151. NULL,
  152. (UINT8)OptCnt,
  153. ReqOpt,
  154. &PktLen,
  155. &Packet
  156. );
  157. if (EFI_ERROR (Status)) {
  158. if (Status == EFI_TFTP_ERROR) {
  159. //
  160. // Store the tftp error message into mode data and set the received flag.
  161. //
  162. Private->Mode.TftpErrorReceived = TRUE;
  163. Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;
  164. AsciiStrnCpyS (
  165. Private->Mode.TftpError.ErrorString,
  166. PXE_MTFTP_ERROR_STRING_LENGTH,
  167. (CHAR8 *)Packet->Error.ErrorMessage,
  168. PXE_MTFTP_ERROR_STRING_LENGTH - 1
  169. );
  170. Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';
  171. }
  172. goto ON_ERROR;
  173. }
  174. //
  175. // Parse the options in the reply packet.
  176. //
  177. OptCnt = 0;
  178. Status = Mtftp6->ParseOptions (
  179. Mtftp6,
  180. PktLen,
  181. Packet,
  182. (UINT32 *)&OptCnt,
  183. &Option
  184. );
  185. if (EFI_ERROR (Status)) {
  186. goto ON_ERROR;
  187. }
  188. //
  189. // Parse out the value of "tsize" option.
  190. //
  191. Status = EFI_NOT_FOUND;
  192. while (OptCnt != 0) {
  193. if (AsciiStrnCmp ((CHAR8 *)Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {
  194. *BufferSize = AsciiStrDecimalToUint64 ((CHAR8 *)(Option[OptCnt - 1].ValueStr));
  195. Status = EFI_SUCCESS;
  196. }
  197. OptCnt--;
  198. }
  199. FreePool (Option);
  200. ON_ERROR:
  201. if (Packet != NULL) {
  202. FreePool (Packet);
  203. }
  204. Mtftp6->Configure (Mtftp6, NULL);
  205. return Status;
  206. }
  207. /**
  208. This function is to get data of a file using Tftp.
  209. @param[in] Private Pointer to PxeBc private data.
  210. @param[in] Config Pointer to EFI_MTFTP6_CONFIG_DATA.
  211. @param[in] Filename Pointer to boot file name.
  212. @param[in] BlockSize Pointer to required block size.
  213. @param[in] WindowSize Pointer to required window size.
  214. @param[in] BufferPtr Pointer to buffer.
  215. @param[in, out] BufferSize Pointer to buffer size.
  216. @param[in] DontUseBuffer Indicates whether with a receive buffer.
  217. @retval EFI_SUCCESS Successfully read the data from the special file.
  218. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
  219. @retval Others Read data from file failed.
  220. **/
  221. EFI_STATUS
  222. PxeBcMtftp6ReadFile (
  223. IN PXEBC_PRIVATE_DATA *Private,
  224. IN EFI_MTFTP6_CONFIG_DATA *Config,
  225. IN UINT8 *Filename,
  226. IN UINTN *BlockSize,
  227. IN UINTN *WindowSize,
  228. IN UINT8 *BufferPtr,
  229. IN OUT UINT64 *BufferSize,
  230. IN BOOLEAN DontUseBuffer
  231. )
  232. {
  233. EFI_MTFTP6_PROTOCOL *Mtftp6;
  234. EFI_MTFTP6_TOKEN Token;
  235. EFI_MTFTP6_OPTION ReqOpt[2];
  236. UINT32 OptCnt;
  237. UINT8 BlksizeBuf[10];
  238. UINT8 WindowsizeBuf[10];
  239. EFI_STATUS Status;
  240. Status = EFI_DEVICE_ERROR;
  241. Mtftp6 = Private->Mtftp6;
  242. OptCnt = 0;
  243. Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
  244. Status = Mtftp6->Configure (Mtftp6, Config);
  245. if (EFI_ERROR (Status)) {
  246. return Status;
  247. }
  248. if (BlockSize != NULL) {
  249. ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
  250. ReqOpt[OptCnt].ValueStr = BlksizeBuf;
  251. PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));
  252. OptCnt++;
  253. }
  254. if (WindowSize != NULL) {
  255. ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
  256. ReqOpt[OptCnt].ValueStr = WindowsizeBuf;
  257. PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));
  258. OptCnt++;
  259. }
  260. Token.Event = NULL;
  261. Token.OverrideData = NULL;
  262. Token.Filename = Filename;
  263. Token.ModeStr = NULL;
  264. Token.OptionCount = OptCnt;
  265. Token.OptionList = ReqOpt;
  266. Token.Context = Private;
  267. if (DontUseBuffer) {
  268. Token.BufferSize = 0;
  269. Token.Buffer = NULL;
  270. } else {
  271. Token.BufferSize = *BufferSize;
  272. Token.Buffer = BufferPtr;
  273. }
  274. Token.CheckPacket = PxeBcMtftp6CheckPacket;
  275. Token.TimeoutCallback = NULL;
  276. Token.PacketNeeded = NULL;
  277. Status = Mtftp6->ReadFile (Mtftp6, &Token);
  278. //
  279. // Get the real size of received buffer.
  280. //
  281. *BufferSize = Token.BufferSize;
  282. Mtftp6->Configure (Mtftp6, NULL);
  283. return Status;
  284. }
  285. /**
  286. This function is used to write the data of a file using Tftp.
  287. @param[in] Private Pointer to PxeBc private data.
  288. @param[in] Config Pointer to EFI_MTFTP6_CONFIG_DATA.
  289. @param[in] Filename Pointer to boot file name.
  290. @param[in] Overwrite Indicate whether with overwrite attribute.
  291. @param[in] BlockSize Pointer to required block size.
  292. @param[in] BufferPtr Pointer to buffer.
  293. @param[in, out] BufferSize Pointer to buffer size.
  294. @retval EFI_SUCCESS Successfully wrote the data into a special file.
  295. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
  296. @retval other Write data into file failed.
  297. **/
  298. EFI_STATUS
  299. PxeBcMtftp6WriteFile (
  300. IN PXEBC_PRIVATE_DATA *Private,
  301. IN EFI_MTFTP6_CONFIG_DATA *Config,
  302. IN UINT8 *Filename,
  303. IN BOOLEAN Overwrite,
  304. IN UINTN *BlockSize,
  305. IN UINT8 *BufferPtr,
  306. IN OUT UINT64 *BufferSize
  307. )
  308. {
  309. EFI_MTFTP6_PROTOCOL *Mtftp6;
  310. EFI_MTFTP6_TOKEN Token;
  311. EFI_MTFTP6_OPTION ReqOpt[1];
  312. UINT32 OptCnt;
  313. UINT8 OptBuf[128];
  314. EFI_STATUS Status;
  315. Status = EFI_DEVICE_ERROR;
  316. Mtftp6 = Private->Mtftp6;
  317. OptCnt = 0;
  318. Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
  319. Status = Mtftp6->Configure (Mtftp6, Config);
  320. if (EFI_ERROR (Status)) {
  321. return Status;
  322. }
  323. if (BlockSize != NULL) {
  324. ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
  325. ReqOpt[0].ValueStr = OptBuf;
  326. PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr, PXE_MTFTP_OPTBUF_MAXNUM_INDEX);
  327. OptCnt++;
  328. }
  329. Token.Event = NULL;
  330. Token.OverrideData = NULL;
  331. Token.Filename = Filename;
  332. Token.ModeStr = NULL;
  333. Token.OptionCount = OptCnt;
  334. Token.OptionList = ReqOpt;
  335. Token.BufferSize = *BufferSize;
  336. Token.Buffer = BufferPtr;
  337. Token.CheckPacket = PxeBcMtftp6CheckPacket;
  338. Token.TimeoutCallback = NULL;
  339. Token.PacketNeeded = NULL;
  340. Status = Mtftp6->WriteFile (Mtftp6, &Token);
  341. //
  342. // Get the real size of transmitted buffer.
  343. //
  344. *BufferSize = Token.BufferSize;
  345. Mtftp6->Configure (Mtftp6, NULL);
  346. return Status;
  347. }
  348. /**
  349. This function is to read the data (file) from a directory using Tftp.
  350. @param[in] Private Pointer to PxeBc private data.
  351. @param[in] Config Pointer to EFI_MTFTP6_CONFIG_DATA.
  352. @param[in] Filename Pointer to boot file name.
  353. @param[in] BlockSize Pointer to required block size.
  354. @param[in] WindowSize Pointer to required window size.
  355. @param[in] BufferPtr Pointer to buffer.
  356. @param[in, out] BufferSize Pointer to buffer size.
  357. @param[in] DontUseBuffer Indicates whether to use a receive buffer.
  358. @retval EFI_SUCCESS Successfully obtained the data from the file included in directory.
  359. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
  360. @retval Others Operation failed.
  361. **/
  362. EFI_STATUS
  363. PxeBcMtftp6ReadDirectory (
  364. IN PXEBC_PRIVATE_DATA *Private,
  365. IN EFI_MTFTP6_CONFIG_DATA *Config,
  366. IN UINT8 *Filename,
  367. IN UINTN *BlockSize,
  368. IN UINTN *WindowSize,
  369. IN UINT8 *BufferPtr,
  370. IN OUT UINT64 *BufferSize,
  371. IN BOOLEAN DontUseBuffer
  372. )
  373. {
  374. EFI_MTFTP6_PROTOCOL *Mtftp6;
  375. EFI_MTFTP6_TOKEN Token;
  376. EFI_MTFTP6_OPTION ReqOpt[2];
  377. UINT32 OptCnt;
  378. UINT8 BlksizeBuf[10];
  379. UINT8 WindowsizeBuf[10];
  380. EFI_STATUS Status;
  381. Status = EFI_DEVICE_ERROR;
  382. Mtftp6 = Private->Mtftp6;
  383. OptCnt = 0;
  384. Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
  385. Status = Mtftp6->Configure (Mtftp6, Config);
  386. if (EFI_ERROR (Status)) {
  387. return Status;
  388. }
  389. if (BlockSize != NULL) {
  390. ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
  391. ReqOpt[OptCnt].ValueStr = BlksizeBuf;
  392. PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));
  393. OptCnt++;
  394. }
  395. if (WindowSize != NULL) {
  396. ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
  397. ReqOpt[OptCnt].ValueStr = WindowsizeBuf;
  398. PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));
  399. OptCnt++;
  400. }
  401. Token.Event = NULL;
  402. Token.OverrideData = NULL;
  403. Token.Filename = Filename;
  404. Token.ModeStr = NULL;
  405. Token.OptionCount = OptCnt;
  406. Token.OptionList = ReqOpt;
  407. Token.Context = Private;
  408. if (DontUseBuffer) {
  409. Token.BufferSize = 0;
  410. Token.Buffer = NULL;
  411. } else {
  412. Token.BufferSize = *BufferSize;
  413. Token.Buffer = BufferPtr;
  414. }
  415. Token.CheckPacket = PxeBcMtftp6CheckPacket;
  416. Token.TimeoutCallback = NULL;
  417. Token.PacketNeeded = NULL;
  418. Status = Mtftp6->ReadDirectory (Mtftp6, &Token);
  419. //
  420. // Get the real size of received buffer.
  421. //
  422. *BufferSize = Token.BufferSize;
  423. Mtftp6->Configure (Mtftp6, NULL);
  424. return Status;
  425. }
  426. /**
  427. This is a callback function when packets are received or transmitted in Mtftp driver.
  428. A callback function that is provided by the caller to intercept
  429. the EFI_MTFTP6_OPCODE_DATA or EFI_MTFTP4_OPCODE_DATA8 packets processed in the
  430. EFI_MTFTP4_PROTOCOL.ReadFile() function, and alternatively to intercept
  431. EFI_MTFTP4_OPCODE_OACK or EFI_MTFTP4_OPCODE_ERROR packets during a call to
  432. EFI_MTFTP4_PROTOCOL.ReadFile(), WriteFile() or ReadDirectory().
  433. @param[in] This Pointer to EFI_MTFTP4_PROTOCOL.
  434. @param[in] Token Pointer to EFI_MTFTP4_TOKEN.
  435. @param[in] PacketLen Length of EFI_MTFTP4_PACKET.
  436. @param[in] Packet Pointer to EFI_MTFTP4_PACKET to be checked.
  437. @retval EFI_SUCCESS The current operation succeeded.
  438. @retval EFI_ABORTED Abort the current transfer process.
  439. **/
  440. EFI_STATUS
  441. EFIAPI
  442. PxeBcMtftp4CheckPacket (
  443. IN EFI_MTFTP4_PROTOCOL *This,
  444. IN EFI_MTFTP4_TOKEN *Token,
  445. IN UINT16 PacketLen,
  446. IN EFI_MTFTP4_PACKET *Packet
  447. )
  448. {
  449. PXEBC_PRIVATE_DATA *Private;
  450. EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *Callback;
  451. EFI_STATUS Status;
  452. Private = (PXEBC_PRIVATE_DATA *)Token->Context;
  453. Callback = Private->PxeBcCallback;
  454. Status = EFI_SUCCESS;
  455. if (Packet->OpCode == EFI_MTFTP4_OPCODE_ERROR) {
  456. //
  457. // Store the tftp error message into mode data and set the received flag.
  458. //
  459. Private->Mode.TftpErrorReceived = TRUE;
  460. Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;
  461. AsciiStrnCpyS (
  462. Private->Mode.TftpError.ErrorString,
  463. PXE_MTFTP_ERROR_STRING_LENGTH,
  464. (CHAR8 *)Packet->Error.ErrorMessage,
  465. PXE_MTFTP_ERROR_STRING_LENGTH - 1
  466. );
  467. Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';
  468. }
  469. if (Callback != NULL) {
  470. //
  471. // Callback to user if has when received any tftp packet.
  472. //
  473. Status = Callback->Callback (
  474. Callback,
  475. Private->Function,
  476. TRUE,
  477. PacketLen,
  478. (EFI_PXE_BASE_CODE_PACKET *)Packet
  479. );
  480. if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {
  481. //
  482. // User wants to abort current process if not EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.
  483. //
  484. Status = EFI_ABORTED;
  485. } else {
  486. //
  487. // User wants to continue current process if EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.
  488. //
  489. Status = EFI_SUCCESS;
  490. }
  491. }
  492. return Status;
  493. }
  494. /**
  495. This function is to get size of a file using Tftp.
  496. @param[in] Private Pointer to PxeBc private data.
  497. @param[in] Config Pointer to EFI_MTFTP4_CONFIG_DATA.
  498. @param[in] Filename Pointer to boot file name.
  499. @param[in] BlockSize Pointer to required block size.
  500. @param[in] WindowSize Pointer to required window size.
  501. @param[in, out] BufferSize Pointer to buffer size.
  502. @retval EFI_SUCCESS Successfully obtained the size of file.
  503. @retval EFI_NOT_FOUND Parse the tftp options failed.
  504. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
  505. @retval Others Did not obtain the size of the file.
  506. **/
  507. EFI_STATUS
  508. PxeBcMtftp4GetFileSize (
  509. IN PXEBC_PRIVATE_DATA *Private,
  510. IN EFI_MTFTP4_CONFIG_DATA *Config,
  511. IN UINT8 *Filename,
  512. IN UINTN *BlockSize,
  513. IN UINTN *WindowSize,
  514. IN OUT UINT64 *BufferSize
  515. )
  516. {
  517. EFI_MTFTP4_PROTOCOL *Mtftp4;
  518. EFI_MTFTP4_OPTION ReqOpt[3];
  519. EFI_MTFTP4_PACKET *Packet;
  520. EFI_MTFTP4_OPTION *Option;
  521. UINT32 PktLen;
  522. UINT8 OptBuf[PXE_MTFTP_OPTBUF_MAXNUM_INDEX];
  523. UINTN OptBufSize;
  524. UINT32 OptCnt;
  525. EFI_STATUS Status;
  526. *BufferSize = 0;
  527. Status = EFI_DEVICE_ERROR;
  528. Mtftp4 = Private->Mtftp4;
  529. Packet = NULL;
  530. Option = NULL;
  531. PktLen = 0;
  532. OptBufSize = PXE_MTFTP_OPTBUF_MAXNUM_INDEX;
  533. OptCnt = 1;
  534. Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
  535. Status = Mtftp4->Configure (Mtftp4, Config);
  536. if (EFI_ERROR (Status)) {
  537. return Status;
  538. }
  539. //
  540. // Build the required options for get info.
  541. //
  542. ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];
  543. PxeBcUintnToAscDec (0, OptBuf, OptBufSize);
  544. ReqOpt[0].ValueStr = OptBuf;
  545. if (BlockSize != NULL) {
  546. ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
  547. ReqOpt[OptCnt].ValueStr = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
  548. OptBufSize -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
  549. PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, OptBufSize);
  550. OptCnt++;
  551. }
  552. if (WindowSize != NULL) {
  553. ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
  554. ReqOpt[OptCnt].ValueStr = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
  555. OptBufSize -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);
  556. PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, OptBufSize);
  557. OptCnt++;
  558. }
  559. Status = Mtftp4->GetInfo (
  560. Mtftp4,
  561. NULL,
  562. Filename,
  563. NULL,
  564. (UINT8)OptCnt,
  565. ReqOpt,
  566. &PktLen,
  567. &Packet
  568. );
  569. if (EFI_ERROR (Status)) {
  570. if (Status == EFI_TFTP_ERROR) {
  571. //
  572. // Store the tftp error message into mode data and set the received flag.
  573. //
  574. Private->Mode.TftpErrorReceived = TRUE;
  575. Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;
  576. AsciiStrnCpyS (
  577. Private->Mode.TftpError.ErrorString,
  578. PXE_MTFTP_ERROR_STRING_LENGTH,
  579. (CHAR8 *)Packet->Error.ErrorMessage,
  580. PXE_MTFTP_ERROR_STRING_LENGTH - 1
  581. );
  582. Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';
  583. }
  584. goto ON_ERROR;
  585. }
  586. //
  587. // Parse the options in the reply packet.
  588. //
  589. OptCnt = 0;
  590. Status = Mtftp4->ParseOptions (
  591. Mtftp4,
  592. PktLen,
  593. Packet,
  594. (UINT32 *)&OptCnt,
  595. &Option
  596. );
  597. if (EFI_ERROR (Status)) {
  598. goto ON_ERROR;
  599. }
  600. //
  601. // Parse out the value of "tsize" option.
  602. //
  603. Status = EFI_NOT_FOUND;
  604. while (OptCnt != 0) {
  605. if (AsciiStrnCmp ((CHAR8 *)Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {
  606. *BufferSize = AsciiStrDecimalToUint64 ((CHAR8 *)(Option[OptCnt - 1].ValueStr));
  607. Status = EFI_SUCCESS;
  608. }
  609. OptCnt--;
  610. }
  611. FreePool (Option);
  612. ON_ERROR:
  613. if (Packet != NULL) {
  614. FreePool (Packet);
  615. }
  616. Mtftp4->Configure (Mtftp4, NULL);
  617. return Status;
  618. }
  619. /**
  620. This function is to read the data of a file using Tftp.
  621. @param[in] Private Pointer to PxeBc private data.
  622. @param[in] Config Pointer to EFI_MTFTP4_CONFIG_DATA.
  623. @param[in] Filename Pointer to boot file name.
  624. @param[in] BlockSize Pointer to required block size.
  625. @param[in] WindowSize Pointer to required window size.
  626. @param[in] BufferPtr Pointer to buffer.
  627. @param[in, out] BufferSize Pointer to buffer size.
  628. @param[in] DontUseBuffer Indicates whether to use a receive buffer.
  629. @retval EFI_SUCCESS Successfully read the data from the special file.
  630. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
  631. @retval Others Read data from file failed.
  632. **/
  633. EFI_STATUS
  634. PxeBcMtftp4ReadFile (
  635. IN PXEBC_PRIVATE_DATA *Private,
  636. IN EFI_MTFTP4_CONFIG_DATA *Config,
  637. IN UINT8 *Filename,
  638. IN UINTN *BlockSize,
  639. IN UINTN *WindowSize,
  640. IN UINT8 *BufferPtr,
  641. IN OUT UINT64 *BufferSize,
  642. IN BOOLEAN DontUseBuffer
  643. )
  644. {
  645. EFI_MTFTP4_PROTOCOL *Mtftp4;
  646. EFI_MTFTP4_TOKEN Token;
  647. EFI_MTFTP4_OPTION ReqOpt[2];
  648. UINT32 OptCnt;
  649. UINT8 BlksizeBuf[10];
  650. UINT8 WindowsizeBuf[10];
  651. EFI_STATUS Status;
  652. Status = EFI_DEVICE_ERROR;
  653. Mtftp4 = Private->Mtftp4;
  654. OptCnt = 0;
  655. Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
  656. Status = Mtftp4->Configure (Mtftp4, Config);
  657. if (EFI_ERROR (Status)) {
  658. return Status;
  659. }
  660. if (BlockSize != NULL) {
  661. ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
  662. ReqOpt[OptCnt].ValueStr = BlksizeBuf;
  663. PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));
  664. OptCnt++;
  665. }
  666. if (WindowSize != NULL) {
  667. ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
  668. ReqOpt[OptCnt].ValueStr = WindowsizeBuf;
  669. PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));
  670. OptCnt++;
  671. }
  672. Token.Event = NULL;
  673. Token.OverrideData = NULL;
  674. Token.Filename = Filename;
  675. Token.ModeStr = NULL;
  676. Token.OptionCount = OptCnt;
  677. Token.OptionList = ReqOpt;
  678. Token.Context = Private;
  679. if (DontUseBuffer) {
  680. Token.BufferSize = 0;
  681. Token.Buffer = NULL;
  682. } else {
  683. Token.BufferSize = *BufferSize;
  684. Token.Buffer = BufferPtr;
  685. }
  686. Token.CheckPacket = PxeBcMtftp4CheckPacket;
  687. Token.TimeoutCallback = NULL;
  688. Token.PacketNeeded = NULL;
  689. Status = Mtftp4->ReadFile (Mtftp4, &Token);
  690. //
  691. // Get the real size of received buffer.
  692. //
  693. *BufferSize = Token.BufferSize;
  694. Mtftp4->Configure (Mtftp4, NULL);
  695. return Status;
  696. }
  697. /**
  698. This function is to write the data of a file using Tftp.
  699. @param[in] Private Pointer to PxeBc private data.
  700. @param[in] Config Pointer to EFI_MTFTP4_CONFIG_DATA.
  701. @param[in] Filename Pointer to boot file name.
  702. @param[in] Overwrite Indicates whether to use the overwrite attribute.
  703. @param[in] BlockSize Pointer to required block size.
  704. @param[in] BufferPtr Pointer to buffer.
  705. @param[in, out] BufferSize Pointer to buffer size.
  706. @retval EFI_SUCCESS Successfully write the data into the special file.
  707. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
  708. @retval other Write data into file failed.
  709. **/
  710. EFI_STATUS
  711. PxeBcMtftp4WriteFile (
  712. IN PXEBC_PRIVATE_DATA *Private,
  713. IN EFI_MTFTP4_CONFIG_DATA *Config,
  714. IN UINT8 *Filename,
  715. IN BOOLEAN Overwrite,
  716. IN UINTN *BlockSize,
  717. IN UINT8 *BufferPtr,
  718. IN OUT UINT64 *BufferSize
  719. )
  720. {
  721. EFI_MTFTP4_PROTOCOL *Mtftp4;
  722. EFI_MTFTP4_TOKEN Token;
  723. EFI_MTFTP4_OPTION ReqOpt[1];
  724. UINT32 OptCnt;
  725. UINT8 OptBuf[128];
  726. EFI_STATUS Status;
  727. Status = EFI_DEVICE_ERROR;
  728. Mtftp4 = Private->Mtftp4;
  729. OptCnt = 0;
  730. Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
  731. Status = Mtftp4->Configure (Mtftp4, Config);
  732. if (EFI_ERROR (Status)) {
  733. return Status;
  734. }
  735. if (BlockSize != NULL) {
  736. ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
  737. ReqOpt[0].ValueStr = OptBuf;
  738. PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr, PXE_MTFTP_OPTBUF_MAXNUM_INDEX);
  739. OptCnt++;
  740. }
  741. Token.Event = NULL;
  742. Token.OverrideData = NULL;
  743. Token.Filename = Filename;
  744. Token.ModeStr = NULL;
  745. Token.OptionCount = OptCnt;
  746. Token.OptionList = ReqOpt;
  747. Token.BufferSize = *BufferSize;
  748. Token.Buffer = BufferPtr;
  749. Token.CheckPacket = PxeBcMtftp4CheckPacket;
  750. Token.TimeoutCallback = NULL;
  751. Token.PacketNeeded = NULL;
  752. Status = Mtftp4->WriteFile (Mtftp4, &Token);
  753. //
  754. // Get the real size of transmitted buffer.
  755. //
  756. *BufferSize = Token.BufferSize;
  757. Mtftp4->Configure (Mtftp4, NULL);
  758. return Status;
  759. }
  760. /**
  761. This function is to get data (file) from a directory using Tftp.
  762. @param[in] Private Pointer to PxeBc private data.
  763. @param[in] Config Pointer to EFI_MTFTP4_CONFIG_DATA.
  764. @param[in] Filename Pointer to boot file name.
  765. @param[in] BlockSize Pointer to required block size.
  766. @param[in] WindowSize Pointer to required window size.
  767. @param[in] BufferPtr Pointer to buffer.
  768. @param[in, out] BufferSize Pointer to buffer size.
  769. @param[in] DontUseBuffer Indicates whether to use a receive buffer.
  770. @retval EFI_SUCCESS Successfully obtained the data from the file included in the directory.
  771. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
  772. @retval Others Operation failed.
  773. **/
  774. EFI_STATUS
  775. PxeBcMtftp4ReadDirectory (
  776. IN PXEBC_PRIVATE_DATA *Private,
  777. IN EFI_MTFTP4_CONFIG_DATA *Config,
  778. IN UINT8 *Filename,
  779. IN UINTN *BlockSize,
  780. IN UINTN *WindowSize,
  781. IN UINT8 *BufferPtr,
  782. IN OUT UINT64 *BufferSize,
  783. IN BOOLEAN DontUseBuffer
  784. )
  785. {
  786. EFI_MTFTP4_PROTOCOL *Mtftp4;
  787. EFI_MTFTP4_TOKEN Token;
  788. EFI_MTFTP4_OPTION ReqOpt[2];
  789. UINT32 OptCnt;
  790. UINT8 BlksizeBuf[10];
  791. UINT8 WindowsizeBuf[10];
  792. EFI_STATUS Status;
  793. Status = EFI_DEVICE_ERROR;
  794. Mtftp4 = Private->Mtftp4;
  795. OptCnt = 0;
  796. Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
  797. Status = Mtftp4->Configure (Mtftp4, Config);
  798. if (EFI_ERROR (Status)) {
  799. return Status;
  800. }
  801. if (BlockSize != NULL) {
  802. ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
  803. ReqOpt[OptCnt].ValueStr = BlksizeBuf;
  804. PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));
  805. OptCnt++;
  806. }
  807. if (WindowSize != NULL) {
  808. ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];
  809. ReqOpt[OptCnt].ValueStr = WindowsizeBuf;
  810. PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));
  811. OptCnt++;
  812. }
  813. Token.Event = NULL;
  814. Token.OverrideData = NULL;
  815. Token.Filename = Filename;
  816. Token.ModeStr = NULL;
  817. Token.OptionCount = OptCnt;
  818. Token.OptionList = ReqOpt;
  819. Token.Context = Private;
  820. if (DontUseBuffer) {
  821. Token.BufferSize = 0;
  822. Token.Buffer = NULL;
  823. } else {
  824. Token.BufferSize = *BufferSize;
  825. Token.Buffer = BufferPtr;
  826. }
  827. Token.CheckPacket = PxeBcMtftp4CheckPacket;
  828. Token.TimeoutCallback = NULL;
  829. Token.PacketNeeded = NULL;
  830. Status = Mtftp4->ReadDirectory (Mtftp4, &Token);
  831. //
  832. // Get the real size of received buffer.
  833. //
  834. *BufferSize = Token.BufferSize;
  835. Mtftp4->Configure (Mtftp4, NULL);
  836. return Status;
  837. }
  838. /**
  839. This function is wrapper to get the file size using TFTP.
  840. @param[in] Private Pointer to PxeBc private data.
  841. @param[in] Config Pointer to configure data.
  842. @param[in] Filename Pointer to boot file name.
  843. @param[in] BlockSize Pointer to required block size.
  844. @param[in] WindowSize Pointer to required window size.
  845. @param[in, out] BufferSize Pointer to buffer size.
  846. @retval EFI_SUCCESS Successfully obtained the size of file.
  847. @retval EFI_NOT_FOUND Parse the tftp options failed.
  848. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
  849. @retval Others Did not obtain the size of the file.
  850. **/
  851. EFI_STATUS
  852. PxeBcTftpGetFileSize (
  853. IN PXEBC_PRIVATE_DATA *Private,
  854. IN VOID *Config,
  855. IN UINT8 *Filename,
  856. IN UINTN *BlockSize,
  857. IN UINTN *WindowSize,
  858. IN OUT UINT64 *BufferSize
  859. )
  860. {
  861. if (Private->PxeBc.Mode->UsingIpv6) {
  862. return PxeBcMtftp6GetFileSize (
  863. Private,
  864. (EFI_MTFTP6_CONFIG_DATA *)Config,
  865. Filename,
  866. BlockSize,
  867. WindowSize,
  868. BufferSize
  869. );
  870. } else {
  871. return PxeBcMtftp4GetFileSize (
  872. Private,
  873. (EFI_MTFTP4_CONFIG_DATA *)Config,
  874. Filename,
  875. BlockSize,
  876. WindowSize,
  877. BufferSize
  878. );
  879. }
  880. }
  881. /**
  882. This function is a wrapper to get file using TFTP.
  883. @param[in] Private Pointer to PxeBc private data.
  884. @param[in] Config Pointer to config data.
  885. @param[in] Filename Pointer to boot file name.
  886. @param[in] BlockSize Pointer to required block size.
  887. @param[in] WindowSize Pointer to required window size.
  888. @param[in] BufferPtr Pointer to buffer.
  889. @param[in, out] BufferSize Pointer to buffer size.
  890. @param[in] DontUseBuffer Indicates whether to use a receive buffer.
  891. @retval EFI_SUCCESS Successfully read the data from the special file.
  892. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
  893. @retval Others Read data from file failed.
  894. **/
  895. EFI_STATUS
  896. PxeBcTftpReadFile (
  897. IN PXEBC_PRIVATE_DATA *Private,
  898. IN VOID *Config,
  899. IN UINT8 *Filename,
  900. IN UINTN *BlockSize,
  901. IN UINTN *WindowSize,
  902. IN UINT8 *BufferPtr,
  903. IN OUT UINT64 *BufferSize,
  904. IN BOOLEAN DontUseBuffer
  905. )
  906. {
  907. if (Private->PxeBc.Mode->UsingIpv6) {
  908. return PxeBcMtftp6ReadFile (
  909. Private,
  910. (EFI_MTFTP6_CONFIG_DATA *)Config,
  911. Filename,
  912. BlockSize,
  913. WindowSize,
  914. BufferPtr,
  915. BufferSize,
  916. DontUseBuffer
  917. );
  918. } else {
  919. return PxeBcMtftp4ReadFile (
  920. Private,
  921. (EFI_MTFTP4_CONFIG_DATA *)Config,
  922. Filename,
  923. BlockSize,
  924. WindowSize,
  925. BufferPtr,
  926. BufferSize,
  927. DontUseBuffer
  928. );
  929. }
  930. }
  931. /**
  932. This function is a wrapper to write file using TFTP.
  933. @param[in] Private Pointer to PxeBc private data.
  934. @param[in] Config Pointer to config data.
  935. @param[in] Filename Pointer to boot file name.
  936. @param[in] Overwrite Indicate whether with overwrite attribute.
  937. @param[in] BlockSize Pointer to required block size.
  938. @param[in] BufferPtr Pointer to buffer.
  939. @param[in, out] BufferSize Pointer to buffer size.
  940. @retval EFI_SUCCESS Successfully wrote the data into a special file.
  941. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
  942. @retval other Write data into file failed.
  943. **/
  944. EFI_STATUS
  945. PxeBcTftpWriteFile (
  946. IN PXEBC_PRIVATE_DATA *Private,
  947. IN VOID *Config,
  948. IN UINT8 *Filename,
  949. IN BOOLEAN Overwrite,
  950. IN UINTN *BlockSize,
  951. IN UINT8 *BufferPtr,
  952. IN OUT UINT64 *BufferSize
  953. )
  954. {
  955. if (Private->PxeBc.Mode->UsingIpv6) {
  956. return PxeBcMtftp6WriteFile (
  957. Private,
  958. (EFI_MTFTP6_CONFIG_DATA *)Config,
  959. Filename,
  960. Overwrite,
  961. BlockSize,
  962. BufferPtr,
  963. BufferSize
  964. );
  965. } else {
  966. return PxeBcMtftp4WriteFile (
  967. Private,
  968. (EFI_MTFTP4_CONFIG_DATA *)Config,
  969. Filename,
  970. Overwrite,
  971. BlockSize,
  972. BufferPtr,
  973. BufferSize
  974. );
  975. }
  976. }
  977. /**
  978. This function is a wrapper to get the data (file) from a directory using TFTP.
  979. @param[in] Private Pointer to PxeBc private data.
  980. @param[in] Config Pointer to config data.
  981. @param[in] Filename Pointer to boot file name.
  982. @param[in] BlockSize Pointer to required block size.
  983. @param[in] WindowSize Pointer to required window size.
  984. @param[in] BufferPtr Pointer to buffer.
  985. @param[in, out] BufferSize Pointer to buffer size.
  986. @param[in] DontUseBuffer Indicatse whether to use a receive buffer.
  987. @retval EFI_SUCCESS Successfully obtained the data from the file included in the directory.
  988. @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
  989. @retval Others Operation failed.
  990. **/
  991. EFI_STATUS
  992. PxeBcTftpReadDirectory (
  993. IN PXEBC_PRIVATE_DATA *Private,
  994. IN VOID *Config,
  995. IN UINT8 *Filename,
  996. IN UINTN *BlockSize,
  997. IN UINTN *WindowSize,
  998. IN UINT8 *BufferPtr,
  999. IN OUT UINT64 *BufferSize,
  1000. IN BOOLEAN DontUseBuffer
  1001. )
  1002. {
  1003. if (Private->PxeBc.Mode->UsingIpv6) {
  1004. return PxeBcMtftp6ReadDirectory (
  1005. Private,
  1006. (EFI_MTFTP6_CONFIG_DATA *)Config,
  1007. Filename,
  1008. BlockSize,
  1009. WindowSize,
  1010. BufferPtr,
  1011. BufferSize,
  1012. DontUseBuffer
  1013. );
  1014. } else {
  1015. return PxeBcMtftp4ReadDirectory (
  1016. Private,
  1017. (EFI_MTFTP4_CONFIG_DATA *)Config,
  1018. Filename,
  1019. BlockSize,
  1020. WindowSize,
  1021. BufferPtr,
  1022. BufferSize,
  1023. DontUseBuffer
  1024. );
  1025. }
  1026. }