From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-lj1-f178.google.com (mail-lj1-f178.google.com [209.85.208.178]) by mx.groups.io with SMTP id smtpd.web12.610.1588961441144119292 for ; Fri, 08 May 2020 11:10:42 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@broadcom.com header.s=google header.b=IkTNJ62k; spf=pass (domain: broadcom.com, ip: 209.85.208.178, mailfrom: vladimir.olovyannikov@broadcom.com) Received: by mail-lj1-f178.google.com with SMTP id o14so1578587ljp.4 for ; Fri, 08 May 2020 11:10:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:references:in-reply-to:mime-version:thread-index:date :message-id:subject:to:cc; bh=/bU8Gqf+DTstID/u+iI0MTLDy9yylibQk8sngeNYzu0=; b=IkTNJ62kvn4WTjZDRt69Rz4yeWnBwjJJza4z7fI+MRTimKGd0YZahjE6KQVzJWUjBB 9r9s1a6L56ofCspXuIbgLLFU8AYPr5mro1Vu9C+mhaRoGWSeIVW1Lys8ytDoSDJjnPJX 1Zo9WiN0K6O7O6bzNcbwYU+hsR4m9WFtq7+nk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:references:in-reply-to:mime-version :thread-index:date:message-id:subject:to:cc; bh=/bU8Gqf+DTstID/u+iI0MTLDy9yylibQk8sngeNYzu0=; b=Bj2t5PhmKODYiu2UzYcx/tiHxIdNx1k7fAJsayCIq7ghiC6j14kYYUTy5/mA3SPVZg pfSQZtFh0SO9XJm0kjLTcKTgbhBUL5DrEDTwXyW22ckDvIYnl6OKL1Sor8t7zfzn0Yn5 7psQS8QCm/RdrftO7/27SWv0G1qPDZ4ZDb9WPKb8lgDig7lRGVITMfGqQlXB2ZqekOH1 KLrgJBqqyDRCBARTgZ2yc6yeshI5ZpCI0AaOrvB3KbGC6Q/0ThY58kKKpczMbaVTvwUS /c3dtOBsdD9nglcPHDn7UP28KJFFmGxQtMhS22gCNUSMcQVYtTWbla9q9U/N14pYxOjD YQ1Q== X-Gm-Message-State: AOAM5318PXqSmehKGE1sD7r4xwtmOiifbGdi7J5DIGVouI+AghwjYFOd ix0gHfaUabddvz61T5AtlBuiZiiIROEAQZVFHU2mLA== X-Google-Smtp-Source: ABdhPJwCu3Bd2mVSsBqUDxO7McftBJ3H0FO3MOCqJI4GN9BE9qRmefzDdKNDnhJrUt1gP0Y5rZgHMwr1sffzWqD3WvI= X-Received: by 2002:a2e:b4a5:: with SMTP id q5mr2704294ljm.58.1588961438553; Fri, 08 May 2020 11:10:38 -0700 (PDT) From: "Vladimir Olovyannikov" References: <20200125005718.8931-1-vladimir.olovyannikov@broadcom.com> <9a006acebab2c210464a84a99df2e40f@mail.gmail.com> In-Reply-To: MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: AQJ4W5t3jiLGMOGmen4SX/7fj5S7jwIK+0xmApMhucYCYLbCrgGrAeK0AWhvotECIKwdSgJtvsRZpuUKm3A= Date: Fri, 8 May 2020 11:10:34 -0700 Message-ID: <599fc568fc52a786ee3f8c584761b498@mail.gmail.com> Subject: Re: [edk2-devel] [PATCH 1/1] ShellPkg/DynamicCommand: add HttpDynamicCommand To: "Gao, Liming" , devel@edk2.groups.io, "Gao, Zhichao" , samer.el-haj-mahmoud@arm.com, "Ni, Ray" , "Fu, Siyuan" , "Wu, Jiaxin" , Maciej Rabeda Cc: nd Content-Type: text/plain; charset="UTF-8" I have a newer version which supports the functionality discussed earlier. Please review it once I post the update. Thank you, Vladimir -----Original Message----- From: Gao, Liming Sent: Friday, May 8, 2020 8:58 AM To: devel@edk2.groups.io; Gao, Zhichao ; samer.el-haj-mahmoud@arm.com; Vladimir Olovyannikov ; Ni, Ray ; Fu, Siyuan ; Wu, Jiaxin ; Maciej Rabeda Cc: nd ; Gao, Liming Subject: RE: [edk2-devel] [PATCH 1/1] ShellPkg/DynamicCommand: add HttpDynamicCommand Include Maciej for network part. > -----Original Message----- > From: devel@edk2.groups.io On Behalf Of Gao, > Zhichao > Sent: Friday, May 8, 2020 11:56 PM > To: devel@edk2.groups.io; samer.el-haj-mahmoud@arm.com; Vladimir > Olovyannikov ; Ni, > Ray ; Fu, Siyuan ; Wu, Jiaxin > > Cc: nd > Subject: Re: [edk2-devel] [PATCH 1/1] ShellPkg/DynamicCommand: add > HttpDynamicCommand > > I think the NetworkPkg maintainer can give a better comment and the remain > part of the implementation need their help to review. > > Hi Jiaxin/Siyuan, > > Do you have any comments on this? And the implementation is part of > NetworkPkg protocol usage. I am not familiar with this. Please > help to review. > > Thanks, > Zhichao > > > -----Original Message----- > > From: devel@edk2.groups.io On Behalf Of Samer El- > > Haj-Mahmoud > > Sent: Friday, May 8, 2020 5:54 PM > > To: Vladimir Olovyannikov ; > > devel@edk2.groups.io; Ni, Ray ; Gao, Zhichao > > > > Cc: nd > > Subject: Re: [edk2-devel] [PATCH 1/1] ShellPkg/DynamicCommand: add > > HttpDynamicCommand > > > > Any update on this patch? This is a useful command to add to the Shell > > (for both > > testing and deployment/scripting). > > > > > -----Original Message----- > > > From: Vladimir Olovyannikov > > > Sent: Tuesday, April 21, 2020 1:37 PM > > > To: Samer El-Haj-Mahmoud ; > > > devel@edk2.groups.io; Ray Ni ; Zhichao Gao > > > > > > Cc: nd > > > Subject: RE: [edk2-devel] [PATCH 1/1] ShellPkg/DynamicCommand: add > > > HttpDynamicCommand > > > > > > .. Skipped.. > > > > Thanks Vladimir for the explanation. > > > > > > > > Wondering what is more useful to users: > > > > > > > > 1- Having the 'http' and 'tftp' commands share a common interface > > > > to > > > > make > > > > it easier to script using either tool/protocol (as explained below) > > > > Or > > > > 2- Having a more natural support for URIs in 'http' command, > > > > similar to > > > > what > > > > is common in other http CLI clients like curl > > > > > > > > If (1) is important enough for users, then could we entertain adding > > > > (2) > > > > in > > > > addition to (1). > > > Thank you for the feedback Samer, > > > Well, (1) is important for us as we use universal UEFI Shell scripts > > > for > > > multiple images updates from any media (usb, network(http/tftp), etc.) > > > I agree that adding (2) to (1) makes sense. Would be nice to get more > > > feedback from edk2 community on that. > > > > > > Thank you, > > > Vladimir > > > > > > > > Thanks, > > > > --Samer > > > > > > > > > > > > > -----Original Message----- > > > > > From: Vladimir Olovyannikov > > > > > Sent: Monday, April 20, 2020 1:10 PM > > > > > To: Samer El-Haj-Mahmoud ; > > > > > devel@edk2.groups.io; Ray Ni ; Zhichao Gao > > > > > > > > > > Cc: nd > > > > > Subject: RE: [edk2-devel] [PATCH 1/1] ShellPkg/DynamicCommand: add > > > > > HttpDynamicCommand > > > > > > > > > > Hi Samer, > > > > > > -----Original Message----- > > > > > > From: Samer El-Haj-Mahmoud > > > > > > Sent: Sunday, April 19, 2020 5:31 AM > > > > > > To: devel@edk2.groups.io; vladimir.olovyannikov@broadcom.com; > > > Ray > > > > Ni > > > > > > ; Zhichao Gao > > > > > > Cc: nd > > > > > > Subject: RE: [edk2-devel] [PATCH 1/1] ShellPkg/DynamicCommand: > > > > > > add > > > > > > HttpDynamicCommand > > > > > > > > > > > > Tested-By: Samer El-Haj-Mahmoud > > Mahmoud@arm.com> > > > > > > > > > > > > I tested on Aarch64 (RPi4) and the command seems to work well. > > > > > > > > > > > > One question: why is the input arguments "host[:port]" and the > > > > > > remote > > > > > file > > > > > > "http_uri" not treated as a single "http_uri" argument? > > > > > > > > > > > > For example, instead of: > > > > > > fs0:\> http http://192.168.1.1:8080 dir1/file1.dat file2.dat > > > > > > > > > > > > Why not: > > > > > > fs0:\> http http://192.168.1.1:8080/dir1/file1.dat file2.dat > > > > > The idea was to make it 100% compatible with tftp command. > > > > > This way, one could easily support both in one script like this: > > > > > set -v eth_int " -i eth0" > > > > > ... > > > > > # Set update protocol on some low-level init > > > > > set upd_proto http (or tftp, or something else if needed and > > > > > supported) > > > > > ... > > > > > # Set protocol-specific parameters > > > > > if "%u_proto%" == "tftp" then > > > > > set -v tftp_blk_param " -s %tftp_blocksize%" > > > > > set -v tftp_win_param " -w %tftp_windowsize%" > > > > > endif > > > > > ... > > > > > # "Universalize" transfer command > > > > > set -v transfer_cmd "%u_proto% %eth_int% %tftp_blk_param% > > > > > %tftp_win_param% > > > > > %serverip% %tftp_dir%" > > > > > ... > > > > > # Use universal transfer command with no changes for any update > > > protocol > > > > > (be it tftp, http, etc.). > > > > > %transfer_cmd%/md5sum.txt %esp_root%\md5sum.txt > > > > > ... > > > > > > > > > > Thanks, > > > > > Vladimir > > > > > > > > > > > > > > > > > > > > > > > > > -----Original Message----- > > > > > > > From: devel@edk2.groups.io On Behalf Of > > > > > > Vladimir > > > > > > > Olovyannikov via Groups.Io > > > > > > > Sent: Friday, January 24, 2020 7:57 PM > > > > > > > To: devel@edk2.groups.io; Ray Ni ; Zhichao > > > > > > > Gao > > > > > > > > > > > > > > Cc: Vladimir Olovyannikov > > > > > > > Subject: [edk2-devel] [PATCH 1/1] ShellPkg/DynamicCommand: add > > > > > > > HttpDynamicCommand > > > > > > > > > > > > > > Introduce an http client utilizing EDK2 HTTP protocol, to > > > > > > > allow fast image downloading from http/https servers. > > > > > > > HTTP download speed is usually x30 times faster than tftp. > > > > > > > The client is based on the same approach as tftp dynamic > > > > > > > command, > > > > and > > > > > > > uses the same UEFI Shell command line parameters. This makes > > > > > > > it > > > easy > > > > > > > integrating http into existing UEFI Shell scripts. > > > > > > > Note that to enable HTTP download, feature Pcd > > > > > > > gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections must > > > > > > > be set to TRUE. > > > > > > > > > > > > > > Signed-off-by: Vladimir Olovyannikov > > > > > > > > > > > > > --- > > > > > > > .../DynamicCommand/HttpDynamicCommand/Http.c | 1639 > > > > > > > +++++++++++++++++ > > > > > > > .../DynamicCommand/HttpDynamicCommand/Http.h | 88 + > > > > > > > .../HttpDynamicCommand/Http.uni | 95 + > > > > > > > .../HttpDynamicCommand/HttpApp.c | 53 + > > > > > > > .../HttpDynamicCommand/HttpApp.inf | 58 + > > > > > > > .../HttpDynamicCommand/HttpDynamicCommand.c | 134 ++ > > > > > > > .../HttpDynamicCommand/HttpDynamicCommand.inf | 63 + > > > > > > > ShellPkg/Include/Guid/ShellLibHiiGuid.h | 7 +- > > > > > > > ShellPkg/ShellPkg.dec | 1 + > > > > > > > ShellPkg/ShellPkg.dsc | 5 + > > > > > > > 10 files changed, 2142 insertions(+), 1 deletion(-) > > > > > > > create mode 100644 > > > > > > > ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c > > > > > > > create mode 100644 > > > > > > > ShellPkg/DynamicCommand/HttpDynamicCommand/Http.h > > > > > > > create mode 100644 > > > > > > > ShellPkg/DynamicCommand/HttpDynamicCommand/Http.uni > > > > > > > create mode 100644 > > > > > > > ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.c > > > > > > > create mode 100644 > > > > > > > ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf > > > > > > > create mode 100644 > > > > > > > > > > > > > > > > > > > > ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand > > > > > > .c > > > > > > > create mode 100644 > > > > > > > > > > > > > > > > > > > > ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand > > > > > > .in > > > > > > > f > > > > > > > > > > > > > > diff --git > > > a/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c > > > > > > > b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c > > > > > > > new file mode 100644 > > > > > > > index 000000000000..4e0af3417348 > > > > > > > --- /dev/null > > > > > > > +++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c > > > > > > > @@ -0,0 +1,1639 @@ > > > > > > > +/** @file > > > > > > > + The implementation for the 'http' Shell command. > > > > > > > + > > > > > > > + Copyright (c) 2015, ARM Ltd. All rights reserved.
> > > > > > > + Copyright (c) 2015 - 2018, Intel Corporation. All rights > > > > > > > reserved. > > > > >
> > > > > > > + (C) Copyright 2015 Hewlett Packard Enterprise Development > > > LP
> > > > > > > + Copyright (c) 2020, Broadcom. All rights reserved.
> > > > > > > + > > > > > > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > > > > > > +**/ > > > > > > > + > > > > > > > +#include "Http.h" > > > > > > > + > > > > > > > +#define IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH 32 > > > > > > > +EFI_HII_HANDLE mHttpHiiHandle; > > > > > > > + > > > > > > > +/* > > > > > > > + Constant strings and definitions related to the message > > > > > > > + indicating the amount of progress in the dowloading of a > > > > > > > HTTP > > > > > file. > > > > > > > +*/ > > > > > > > + > > > > > > > +// Number of steps in the progression slider > > > > > > > +#define HTTP_PROGRESS_SLIDER_STEPS \ > > > > > > > + ((sizeof (HTTP_PROGR_FRAME) / sizeof (CHAR16)) - 3) > > > > > > > + > > > > > > > +// Size in number of characters plus one (final zero) of the > > > > > > > message > > > > > to > > > > > > > +// indicate the progress of an HTTP download. The format is > > > > > "[(progress > > > > > > slider: > > > > > > > +// 40 characters)] (nb of KBytes downloaded so far: 7 > > > > > > > characters) > > > > > Kb". > > > > > > There > > > > > > > +// are thus the number of characters in HTTP_PROGR_FRAME[] > > > > > > > plus > > > > 11 > > > > > > > characters > > > > > > > +// (2 // spaces, "Kb" and seven characters for the number of > > > > > > > KBytes). > > > > > > > +#define HTTP_PROGRESS_MESSAGE_SIZE \ > > > > > > > + ((sizeof (HTTP_PROGR_FRAME) / sizeof (CHAR16)) + 12) > > > > > > > + > > > > > > > +// > > > > > > > +// Buffer size. Note that larger buffer does not mean better > > > > > > > speed! > > > > > > > +// > > > > > > > +#define DEFAULT_BUF_SIZE SIZE_32KB > > > > > > > +#define MAX_BUF_SIZE SIZE_4MB > > > > > > > + > > > > > > > +#define TIMER_MAX_TIMEOUT_S 10 > > > > > > > + > > > > > > > +// File name to use when URI ends with "/" > > > > > > > +#define DEFAULT_HTML_FILE L"index.html" > > > > > > > +#define DEFAULT_HTTP_PROTO L"http" > > > > > > > + > > > > > > > +// String to delete the HTTP progress message to be able to > > > > > > > update > > > > > > > it > > > > > : > > > > > > > +// (HTTP_PROGRESS_MESSAGE_SIZE-1) '\b' > > > > > > > +#define HTTP_PROGRESS_DEL \ > > > > > > > + > > > > > > > > > > > > > > > > > L"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\ > > > > > > b\b\b\ > > > > > > > +\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" > > > > > > > + > > > > > > > +#define HTTP_KB L"\b\b\b\b\b\b\b\b\b\b" > > > > > > > +// Frame for the progression slider > > > > > > > +#define HTTP_PROGR_FRAME L"[ > > > > > ]" > > > > > > > + > > > > > > > +// String descriptions for server errors > > > > > > > +STATIC CONST CHAR16 *ErrStatusDesc[] = > > > > > > > +{ > > > > > > > + L"400 Bad Request", > > > > > > > + L"401 Unauthorized", > > > > > > > + L"402 Payment required", > > > > > > > + L"403 Forbidden", > > > > > > > + L"404 Not Found", > > > > > > > + L"405 Method not allowed", > > > > > > > + L"406 Not acceptable", > > > > > > > + L"407 Proxy authentication required", > > > > > > > + L"408 Request time out", > > > > > > > + L"409 Conflict", > > > > > > > + L"410 Gone", > > > > > > > + L"411 Length required", > > > > > > > + L"412 Precondition failed", > > > > > > > + L"413 Request entity too large", > > > > > > > + L"414 Request URI to large", > > > > > > > + L"415 Unsupported media type", > > > > > > > + L"416 Requested range not satisfied", > > > > > > > + L"417 Expectation failed", > > > > > > > + L"500 Internal server error", > > > > > > > + L"501 Not implemented", > > > > > > > + L"502 Bad gateway", > > > > > > > + L"503 Service unavailable", > > > > > > > + L"504 Gateway timeout", > > > > > > > + L"505 HTTP version not supported" > > > > > > > +}; > > > > > > > + > > > > > > > +// Local File Handle > > > > > > > +STATIC SHELL_FILE_HANDLE mFileHandle = NULL; > > > > > > > + > > > > > > > +// Path of the local file, Unicode encoded > > > > > > > +STATIC CONST CHAR16 *mLocalFilePath; > > > > > > > + > > > > > > > +STATIC BOOLEAN gRequestCallbackComplete = FALSE; > > > > > > > +STATIC BOOLEAN gResponseCallbackComplete = FALSE; > > > > > > > + > > > > > > > +/** > > > > > > > + Cleans off leading and trailing spaces and tabs. > > > > > > > + > > > > > > > + @param[in] String pointer to the string to trim them off. > > > > > > > +**/ > > > > > > > +STATIC > > > > > > > +EFI_STATUS > > > > > > > +TrimSpaces( > > > > > > > + IN CHAR16 **String > > > > > > > + ) > > > > > > > +{ > > > > > > > + ASSERT(String != NULL); > > > > > > > + ASSERT(*String!= NULL); > > > > > > > + // > > > > > > > + // Remove any spaces and tabs at the beginning of the > > > > > > > (*String). > > > > > > > + // > > > > > > > + while (((*String)[0] == L' ') || ((*String)[0] == L'\t')) { > > > > > > > + CopyMem((*String), (*String)+1, StrSize((*String)) - > > > > > > sizeof((*String)[0])); > > > > > > > + } > > > > > > > + > > > > > > > + // > > > > > > > + // Remove any spaces and tabs at the end of the (*String). > > > > > > > + // > > > > > > > + while ((StrLen (*String) > 0) && > > > > > > > (((*String)[StrLen((*String))-1] > > > > > == L' ') || > > > > > > > ((*String)[StrLen((*String))-1] == L'\t'))) { > > > > > > > + (*String)[StrLen((*String))-1] = CHAR_NULL; > > > > > > > + } > > > > > > > + > > > > > > > + return (EFI_SUCCESS); > > > > > > > +} > > > > > > > + > > > > > > > + > > > > > > > +/* > > > > > > > + * Callbacks for request and response. > > > > > > > + * We just acknowledge that operation has completed here. > > > > > > > + */ > > > > > > > +STATIC > > > > > > > +VOID > > > > > > > +EFIAPI > > > > > > > +RequestCallback ( > > > > > > > + IN EFI_EVENT Event, > > > > > > > + IN VOID *Context > > > > > > > +) > > > > > > > +{ > > > > > > > + gRequestCallbackComplete = TRUE; > > > > > > > +} > > > > > > > + > > > > > > > +STATIC > > > > > > > +VOID > > > > > > > +EFIAPI > > > > > > > +ResponseCallback ( > > > > > > > + IN EFI_EVENT Event, > > > > > > > + IN VOID *Context > > > > > > > +) > > > > > > > +{ > > > > > > > + gResponseCallbackComplete = TRUE; > > > > > > > +} > > > > > > > + > > > > > > > + > > > > > > > +/** > > > > > > > + Check and convert the UINT16 option values of the 'http' > > > > > > > command > > > > > > > + > > > > > > > + @param[in] ValueStr Value as an Unicode encoded string > > > > > > > + @param[out] Value UINT16 value > > > > > > > + > > > > > > > + @return TRUE The value was returned. > > > > > > > + @return FALSE A parsing error occured. > > > > > > > +**/ > > > > > > > +STATIC > > > > > > > +BOOLEAN > > > > > > > +StringToUint16 ( > > > > > > > + IN CONST CHAR16 *ValueStr, > > > > > > > + OUT UINT16 *Value > > > > > > > + ); > > > > > > > + > > > > > > > +/** > > > > > > > + Get the name of the NIC. > > > > > > > + > > > > > > > + @param[in] ControllerHandle The network physical device > > > > > > > handle. > > > > > > > + @param[in] NicNumber The network physical device > > > > > > > number. > > > > > > > + @param[out] NicName Address where to store the > > > > > > > NIC > > > > > > > name. > > > > > > > + The memory area has to be at > > > > > > > least > > > > > > > + > > > > > IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH > > > > > > > + double byte wide. > > > > > > > + > > > > > > > + @return EFI_SUCCESS The name of the NIC was returned. > > > > > > > + @return Others The creation of the child for the > > > > > > > Managed > > > > > > > + Network Service failed or the opening > > > > > > > of > > > > > > > + the Managed Network Protocol failed > > > > > > > or > > > > > > > + the operational parameters for the > > > > > > > + Managed Network Protocol could not be > > > > > > > + read. > > > > > > > +**/ > > > > > > > +STATIC > > > > > > > +EFI_STATUS > > > > > > > +GetNicName ( > > > > > > > + IN EFI_HANDLE ControllerHandle, > > > > > > > + IN UINTN NicNumber, > > > > > > > + OUT CHAR16 *NicName > > > > > > > + ); > > > > > > > + > > > > > > > +/** > > > > > > > + Create a child for the service identified by its service > > > > > > > binding > > > > > protocol > > > > > > GUID > > > > > > > + and get from the child the interface of the protocol > > > > > > > identified > > > > > > > by > > > > > its > > > > > > GUID. > > > > > > > + > > > > > > > + @param[in] ControllerHandle Controller handle. > > > > > > > + @param[in] ServiceBindingProtocolGuid Service binding > > > > > > > protocol > > > > > GUID > > > > > > of > > > > > > > the > > > > > > > + service to be > > > > > > > created. > > > > > > > + @param[in] ProtocolGuid GUID of the > > > > > > > protocol to > > > > > > > be > > > > > open. > > > > > > > + @param[out] ChildHandle Address where the > > > > > > > handler > > > > > of the > > > > > > > + created child is > > > > > > > returned. > > > > > NULL is > > > > > > > + returned in case > > > > > > > of > > > > > > > error. > > > > > > > + @param[out] Interface Address where a > > > > > > > pointer > > > > > > > to > > > > > the > > > > > > > + protocol interface > > > > > > > is > > > > > returned in > > > > > > > + case of success. > > > > > > > + > > > > > > > + @return EFI_SUCCESS The child was created and the > > > > > > > protocol > > > > > opened. > > > > > > > + @return Others Either the creation of the child or > > > > > > > the > > > > > opening > > > > > > > + of the protocol failed. > > > > > > > +**/ > > > > > > > +STATIC > > > > > > > +EFI_STATUS > > > > > > > +CreateServiceChildAndOpenProtocol ( > > > > > > > + IN EFI_HANDLE ControllerHandle, > > > > > > > + IN EFI_GUID *ServiceBindingProtocolGuid, > > > > > > > + IN EFI_GUID *ProtocolGuid, > > > > > > > + OUT EFI_HANDLE *ChildHandle, > > > > > > > + OUT VOID **Interface > > > > > > > + ); > > > > > > > + > > > > > > > +/** > > > > > > > + Close the protocol identified by its GUID on the child > > > > > > > handle of > > > > > the > > > > > > service > > > > > > > + identified by its service binding protocol GUID, then > > > > > > > destroy the > > > > > child > > > > > > > + handle. > > > > > > > + > > > > > > > + @param[in] ControllerHandle Controller handle. > > > > > > > + @param[in] ServiceBindingProtocolGuid Service binding > > > > > > > protocol > > > > > GUID > > > > > > of > > > > > > > the > > > > > > > + service to be > > > > > > > destroyed. > > > > > > > + @param[in] ProtocolGuid GUID of the > > > > > > > protocol to > > > > > > > be > > > > > closed. > > > > > > > + @param[in] ChildHandle Handle of the child > > > > > > > to be > > > > > destroyed. > > > > > > > + > > > > > > > +**/ > > > > > > > +STATIC > > > > > > > +VOID > > > > > > > +CloseProtocolAndDestroyServiceChild ( > > > > > > > + IN EFI_HANDLE ControllerHandle, > > > > > > > + IN EFI_GUID *ServiceBindingProtocolGuid, > > > > > > > + IN EFI_GUID *ProtocolGuid, > > > > > > > + IN EFI_HANDLE ChildHandle > > > > > > > + ); > > > > > > > + > > > > > > > + > > > > > > > +/** > > > > > > > + Worker function that download the data of a file from a > > > > > > > HTTP > > > > > > > server > > > > > > given > > > > > > > + the path of the file and its size. > > > > > > > + > > > > > > > + @param[in] Context A pointer to the download > > > > > > > context. > > > > > > > + > > > > > > > + @retval EFI_SUCCESS The file was downloaded. > > > > > > > + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. > > > > > > > + @retval Others The downloading of the file > > > > > > > + from the server failed. > > > > > > > + > > > > > > > +**/ > > > > > > > +STATIC > > > > > > > +EFI_STATUS > > > > > > > +DownloadFile ( > > > > > > > + IN DOWNLOAD_CONTEXT *Context > > > > > > > + ); > > > > > > > + > > > > > > > +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { > > > > > > > + {L"-i", TypeValue}, > > > > > > > + {L"-l", TypeValue}, > > > > > > > + {L"-p", TypeValue}, > > > > > > > + {L"-s", TypeValue}, > > > > > > > + {L"-t", TypeValue}, > > > > > > > + {NULL , TypeMax} > > > > > > > + }; > > > > > > > + > > > > > > > +/** > > > > > > > + Function for 'http' command. > > > > > > > + > > > > > > > + @param[in] ImageHandle Handle to the Image (NULL if > > > > > > > Internal). > > > > > > > + @param[in] SystemTable Pointer to the System Table (NULL > > > > > > > if > > > > > Internal). > > > > > > > + > > > > > > > + @return SHELL_SUCCESS The 'http' command > > > > > > > completed > > > > > > successfully. > > > > > > > + @return SHELL_ABORTED The Shell Library > > > > > > > initialization > > > > > failed. > > > > > > > + @return SHELL_INVALID_PARAMETER At least one of the > > > > command's > > > > > > > arguments is > > > > > > > + not valid. > > > > > > > + @return SHELL_OUT_OF_RESOURCES A memory allocation > > > failed. > > > > > > > + @return SHELL_NOT_FOUND Network Interface Card > > > > > > > not > > > > found. > > > > > > > + @return SHELL_UNSUPPORTED Command was valid, but > > > > > > > the > > > > server > > > > > > > returned > > > > > > > + a status code indicating > > > > > > > some > > > > > error. > > > > > > > + Examine the file > > > > > > > requested for > > > > > error body. > > > > > > > + > > > > > > > +**/ > > > > > > > +SHELL_STATUS > > > > > > > +RunHttp ( > > > > > > > + IN EFI_HANDLE ImageHandle, > > > > > > > + IN EFI_SYSTEM_TABLE *SystemTable > > > > > > > + ) > > > > > > > +{ > > > > > > > + EFI_STATUS Status; > > > > > > > + LIST_ENTRY *CheckPackage; > > > > > > > + CHAR16 *ProblemParam; > > > > > > > + UINTN ParamCount; > > > > > > > + CONST CHAR16 *UserNicName; > > > > > > > + BOOLEAN NicFound; > > > > > > > + CONST CHAR16 *ValueStr; > > > > > > > + CONST CHAR16 *RemoteFilePath; > > > > > > > + CONST CHAR16 *Walker; > > > > > > > + CONST CHAR16 *ProxyServerAddr; > > > > > > > + EFI_HTTP_CONFIG_DATA HttpConfigData; > > > > > > > + EFI_HTTPv4_ACCESS_POINT IPv4Node; > > > > > > > + EFI_HANDLE *Handles; > > > > > > > + UINTN HandleCount; > > > > > > > + UINTN NicNumber; > > > > > > > + UINTN InitialSize; > > > > > > > + CHAR16 > > > > > > > NicName[IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH]; > > > > > > > + EFI_HANDLE ControllerHandle; > > > > > > > + EFI_HANDLE HttpChildHandle; > > > > > > > + DOWNLOAD_CONTEXT Context; > > > > > > > + > > > > > > > + ProblemParam = NULL; > > > > > > > + NicFound = FALSE; > > > > > > > + Handles = NULL; > > > > > > > + > > > > > > > + // > > > > > > > + // Initialize the Shell library (we must be in > > > > > > > non-auto-init...) > > > > > > > + // > > > > > > > + Status = ShellInitialize (); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + ASSERT_EFI_ERROR (Status); > > > > > > > + return SHELL_ABORTED; > > > > > > > + } > > > > > > > + > > > > > > > + ZeroMem (&Context, sizeof (Context)); > > > > > > > + > > > > > > > + // > > > > > > > + // Parse the command line. > > > > > > > + // > > > > > > > + Status = ShellCommandLineParse (ParamList, &CheckPackage, > > > > > > > &ProblemParam, TRUE); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + if ((Status == EFI_VOLUME_CORRUPTED) && > > > > > > > + (ProblemParam != NULL) ) { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), > > > > mHttpHiiHandle, > > > > > > > + HTTP_APP_NAME, ProblemParam > > > > > > > + ); > > > > > > > + SHELL_FREE_NON_NULL (ProblemParam); > > > > > > > + } else { > > > > > > > + ASSERT (FALSE); > > > > > > > + } > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + // > > > > > > > + // Check the number of parameters > > > > > > > + // > > > > > > > + Status = EFI_INVALID_PARAMETER; > > > > > > > + > > > > > > > + ParamCount = ShellCommandLineGetCount (CheckPackage); > > > > > > > + if (ParamCount > 4) { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), > > > > > > > + mHttpHiiHandle, HTTP_APP_NAME > > > > > > > + ); > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + if (ParamCount < 3) { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), > > > > > > > + mHttpHiiHandle, HTTP_APP_NAME > > > > > > > + ); > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + ZeroMem (&HttpConfigData, sizeof (HttpConfigData)); > > > > > > > + ZeroMem (&IPv4Node, sizeof (IPv4Node)); > > > > > > > + IPv4Node.UseDefaultAddress = TRUE; > > > > > > > + > > > > > > > + HttpConfigData.HttpVersion = HttpVersion11; > > > > > > > + HttpConfigData.AccessPoint.IPv4Node = &IPv4Node; > > > > > > > + > > > > > > > + // > > > > > > > + // Get the host address (not necessarily IPv4 format) > > > > > > > + // > > > > > > > + ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1); > > > > > > > + if (!ValueStr) { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), > > > > > > mHttpHiiHandle, > > > > > > > + HTTP_APP_NAME, ValueStr > > > > > > > + ); > > > > > > > + goto Error; > > > > > > > + } else { > > > > > > > + UINTN StartSize; > > > > > > > + > > > > > > > + StartSize = 0; > > > > > > > + if (!StrStr (ValueStr, L"://")) { > > > > > > > + Context.ServerAddrAndProto = StrnCatGrow ( > > > > > > > + > > > > > > > &Context.ServerAddrAndProto, > > > > > > > + &StartSize, > > > > > > > + DEFAULT_HTTP_PROTO, > > > > > > > + StrLen > > > > > > > (DEFAULT_HTTP_PROTO) > > > > > > > + ); > > > > > > > + Context.ServerAddrAndProto = StrnCatGrow ( > > > > > > > + > > > > > > > &Context.ServerAddrAndProto, > > > > > > > + &StartSize, > > > > > > > + L"://", > > > > > > > + StrLen (L"://") > > > > > > > + ); > > > > > > > + } > > > > > > > + > > > > > > > + Context.ServerAddrAndProto = StrnCatGrow ( > > > > > > > + > > > > > > > &Context.ServerAddrAndProto, > > > > > > > + &StartSize, > > > > > > > + ValueStr, > > > > > > > + StrLen (ValueStr) > > > > > > > + ); > > > > > > > + if (!Context.ServerAddrAndProto) { > > > > > > > + Status = EFI_OUT_OF_RESOURCES; > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + } > > > > > > > + > > > > > > > + RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, > > > > 2); > > > > > > > + ASSERT (RemoteFilePath != NULL); > > > > > > > + if (RemoteFilePath) { > > > > > > > + TrimSpaces ((CHAR16 **)&RemoteFilePath); > > > > > > > + } else { > > > > > > > + Status = EFI_INVALID_PARAMETER; > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + if (ParamCount == 4) { > > > > > > > + mLocalFilePath = ShellCommandLineGetRawValue > > > > > > > (CheckPackage, > > > > 3); > > > > > > > + } else { > > > > > > > + Walker = RemoteFilePath + StrLen (RemoteFilePath); > > > > > > > + while ((--Walker) >= RemoteFilePath) { > > > > > > > + if ((*Walker == L'\\') || > > > > > > > + (*Walker == L'/' ) ) { > > > > > > > + break; > > > > > > > + } > > > > > > > + } > > > > > > > + > > > > > > > + mLocalFilePath = Walker + 1; > > > > > > > + } > > > > > > > + > > > > > > > + if (!StrLen (mLocalFilePath)) { > > > > > > > + mLocalFilePath = DEFAULT_HTML_FILE; > > > > > > > + } > > > > > > > + > > > > > > > + InitialSize = 0; > > > > > > > + Context.URI = StrnCatGrow ( > > > > > > > + &Context.URI, > > > > > > > + &InitialSize, > > > > > > > + RemoteFilePath, > > > > > > > + StrLen (RemoteFilePath) > > > > > > > + ); > > > > > > > + if (!Context.URI) { > > > > > > > + Status = EFI_OUT_OF_RESOURCES; > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + // > > > > > > > + // Get the name of the Network Interface Card to be used if > > > > > > > any. > > > > > > > + // > > > > > > > + UserNicName = ShellCommandLineGetValue (CheckPackage, > > > > > > > L"-i"); > > > > > > > + > > > > > > > + ValueStr = ShellCommandLineGetValue (CheckPackage, L"-l"); > > > > > > > + if (ValueStr != NULL) { > > > > > > > + if (!StringToUint16 ( > > > > > > > + ValueStr, > > > > > > > + &HttpConfigData.AccessPoint.IPv4Node->LocalPort > > > > > > > + ) > > > > > > > + ) { > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + } > > > > > > > + > > > > > > > + // Is proxy server used? > > > > > > > + ProxyServerAddr = ShellCommandLineGetValue (CheckPackage, > > > > > > > L"- > > > > p"); > > > > > > > + if (ProxyServerAddr) { > > > > > > > + UINTN StringSize; > > > > > > > + > > > > > > > + StringSize = StrLen (ProxyServerAddr) + 1; > > > > > > > + Context.ProxyServerAddr = AllocatePool (StringSize); > > > > > > > + if (!Context.ProxyServerAddr) { > > > > > > > + Status = EFI_OUT_OF_RESOURCES; > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + UnicodeStrToAsciiStrS ( > > > > > > > + ProxyServerAddr, > > > > > > > + Context.ProxyServerAddr, > > > > > > > + StringSize > > > > > > > + ); > > > > > > > + } > > > > > > > + > > > > > > > + Context.BufferSize = DEFAULT_BUF_SIZE; > > > > > > > + > > > > > > > + // By default, the buffer size is 1M. This can be changed > > > > > > > with -s > > > > > > parameter. > > > > > > > + ValueStr = ShellCommandLineGetValue (CheckPackage, L"-s"); > > > > > > > + if (ValueStr != NULL) { > > > > > > > + Context.BufferSize = ShellStrToUintn (ValueStr); > > > > > > > + if (!Context.BufferSize || Context.BufferSize > > > > > > > > MAX_BUF_SIZE) > > > > > > > { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), > > > > > > > + mHttpHiiHandle, HTTP_APP_NAME, ValueStr > > > > > > > + ); > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + } > > > > > > > + > > > > > > > + ValueStr = ShellCommandLineGetValue (CheckPackage, L"-t"); > > > > > > > + if (ValueStr != NULL) { > > > > > > > + HttpConfigData.TimeOutMillisec = ShellStrToUintn > > > > > > > (ValueStr); > > > > > > > + } > > > > > > > + > > > > > > > + // > > > > > > > + // Locate all HTTP Service Binding protocols > > > > > > > + // > > > > > > > + Status = gBS->LocateHandleBuffer ( > > > > > > > + ByProtocol, > > > > > > > + &gEfiManagedNetworkServiceBindingProtocolGuid, > > > > > > > + NULL, > > > > > > > + &HandleCount, > > > > > > > + &Handles > > > > > > > + ); > > > > > > > + if (EFI_ERROR (Status) || (HandleCount == 0)) { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_HTTP_ERR_NO_NIC), > > > > > > mHttpHiiHandle > > > > > > > + ); > > > > > > > + if (!EFI_ERROR (Status)) { > > > > > > > + Status = EFI_NOT_FOUND; > > > > > > > + } > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + Status = EFI_NOT_FOUND; > > > > > > > + > > > > > > > + for (NicNumber = 0; > > > > > > > + (NicNumber < HandleCount) && (Status != EFI_SUCCESS); > > > > > > > + NicNumber++) { > > > > > > > + ControllerHandle = Handles[NicNumber]; > > > > > > > + > > > > > > > + Status = GetNicName (ControllerHandle, NicNumber, > > > > > > > NicName); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_HTTP_ERR_NIC_NAME), > > > > > > > + mHttpHiiHandle, NicNumber, Status > > > > > > > + ); > > > > > > > + continue; > > > > > > > + } > > > > > > > + > > > > > > > + if (UserNicName != NULL) { > > > > > > > + if (StrCmp (NicName, UserNicName) != 0) { > > > > > > > + continue; > > > > > > > + } > > > > > > > + NicFound = TRUE; > > > > > > > + } > > > > > > > + > > > > > > > + Status = CreateServiceChildAndOpenProtocol ( > > > > > > > + ControllerHandle, > > > > > > > + &gEfiHttpServiceBindingProtocolGuid, > > > > > > > + &gEfiHttpProtocolGuid, > > > > > > > + &HttpChildHandle, > > > > > > > + (VOID**)&Context.Http > > > > > > > + ); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN > > > (STR_HTTP_ERR_OPEN_PROTOCOL), > > > > > > > + mHttpHiiHandle, NicName, Status > > > > > > > + ); > > > > > > > + continue; > > > > > > > + } > > > > > > > + > > > > > > > + Status = Context.Http->Configure (Context.Http, > > > > > > > &HttpConfigData); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_HTTP_ERR_CONFIGURE), > > > > > > > + mHttpHiiHandle, NicName, Status > > > > > > > + ); > > > > > > > + goto NextHandle; > > > > > > > + } > > > > > > > + > > > > > > > + Status = DownloadFile (&Context); > > > > > > > + > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF), > > > > > > > mHttpHiiHandle > > > > > > > + ); > > > > > > > + > > > > > > > + CloseProtocolAndDestroyServiceChild ( > > > > > > > + ControllerHandle, > > > > > > > + &gEfiHttpServiceBindingProtocolGuid, > > > > > > > + &gEfiHttpProtocolGuid, > > > > > > > + HttpChildHandle > > > > > > > + ); > > > > > > > + > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_HTTP_ERR_DOWNLOAD), > > > > > > > + mHttpHiiHandle, RemoteFilePath, NicName, Status > > > > > > > + ); > > > > > > > + // If a user aborted the operation, do not try another > > > > > controller. > > > > > > > + if (Status == EFI_ABORTED) { > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + goto NextHandle; > > > > > > > + } > > > > > > > + > > > > > > > + Status = EFI_SUCCESS; > > > > > > > + > > > > > > > +NextHandle: > > > > > > > + if (Status == EFI_HTTP_ERROR) { > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + } > > > > > > > + > > > > > > > + if ((UserNicName != NULL) && (!NicFound)) { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN > > > (STR_HTTP_ERR_NIC_NOT_FOUND), > > > > > > > + mHttpHiiHandle, UserNicName > > > > > > > + ); > > > > > > > + } > > > > > > > + > > > > > > > +Error: > > > > > > > + ShellCommandLineFreeVarList (CheckPackage); > > > > > > > + SHELL_FREE_NON_NULL (Handles); > > > > > > > + SHELL_FREE_NON_NULL (Context.ProxyServerAddr); > > > > > > > + SHELL_FREE_NON_NULL (Context.ServerAddrAndProto); > > > > > > > + SHELL_FREE_NON_NULL (Context.URI); > > > > > > > + > > > > > > > + return Status & ~MAX_BIT; > > > > > > > +} > > > > > > > + > > > > > > > +/** > > > > > > > + Check and convert the UINT16 option values of the 'http' > > > > > > > command > > > > > > > + > > > > > > > + @param[in] ValueStr Value as an Unicode encoded string > > > > > > > + @param[out] Value UINT16 value > > > > > > > + > > > > > > > + @return TRUE The value was returned. > > > > > > > + @return FALSE A parsing error occured. > > > > > > > +**/ > > > > > > > +STATIC > > > > > > > +BOOLEAN > > > > > > > +StringToUint16 ( > > > > > > > + IN CONST CHAR16 *ValueStr, > > > > > > > + OUT UINT16 *Value > > > > > > > + ) > > > > > > > +{ > > > > > > > + UINTN Val; > > > > > > > + > > > > > > > + Val = ShellStrToUintn (ValueStr); > > > > > > > + if (Val > MAX_UINT16) { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), > > > > > > > + mHttpHiiHandle, HTTP_APP_NAME, ValueStr > > > > > > > + ); > > > > > > > + return FALSE; > > > > > > > + } > > > > > > > + > > > > > > > + *Value = (UINT16)Val; > > > > > > > + return TRUE; > > > > > > > +} > > > > > > > + > > > > > > > +/** > > > > > > > + Get the name of the NIC. > > > > > > > + > > > > > > > + @param[in] ControllerHandle The network physical device > > > > > > > handle. > > > > > > > + @param[in] NicNumber The network physical device > > > > > > > number. > > > > > > > + @param[out] NicName Address where to store the > > > > > > > NIC > > > > > > > name. > > > > > > > + The memory area has to be at > > > > > > > least > > > > > > > + > > > > > IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH > > > > > > > + double byte wide. > > > > > > > + > > > > > > > + @return EFI_SUCCESS The name of the NIC was returned. > > > > > > > + @return Others The creation of the child for the > > > > > > > Managed > > > > > > > + Network Service failed or the opening > > > > > > > of > > > > > > > + the Managed Network Protocol failed > > > > > > > or > > > > > > > + the operational parameters for the > > > > > > > + Managed Network Protocol could not be > > > > > > > + read. > > > > > > > +**/ > > > > > > > +STATIC > > > > > > > +EFI_STATUS > > > > > > > +GetNicName ( > > > > > > > + IN EFI_HANDLE ControllerHandle, > > > > > > > + IN UINTN NicNumber, > > > > > > > + OUT CHAR16 *NicName > > > > > > > + ) > > > > > > > +{ > > > > > > > + EFI_STATUS Status; > > > > > > > + EFI_HANDLE MnpHandle; > > > > > > > + EFI_MANAGED_NETWORK_PROTOCOL *Mnp; > > > > > > > + EFI_SIMPLE_NETWORK_MODE SnpMode; > > > > > > > + > > > > > > > + Status = CreateServiceChildAndOpenProtocol ( > > > > > > > + ControllerHandle, > > > > > > > + &gEfiManagedNetworkServiceBindingProtocolGuid, > > > > > > > + &gEfiManagedNetworkProtocolGuid, > > > > > > > + &MnpHandle, > > > > > > > + (VOID**)&Mnp > > > > > > > + ); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + Status = Mnp->GetModeData (Mnp, NULL, &SnpMode); > > > > > > > + if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) { > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + UnicodeSPrint ( > > > > > > > + NicName, > > > > > > > + IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH, > > > > > > > + SnpMode.IfType == NET_IFTYPE_ETHERNET ? > > > > > > > + L"eth%d" : > > > > > > > + L"unk%d", > > > > > > > + NicNumber > > > > > > > + ); > > > > > > > + > > > > > > > + Status = EFI_SUCCESS; > > > > > > > + > > > > > > > +Error: > > > > > > > + > > > > > > > + if (MnpHandle != NULL) { > > > > > > > + CloseProtocolAndDestroyServiceChild ( > > > > > > > + ControllerHandle, > > > > > > > + &gEfiManagedNetworkServiceBindingProtocolGuid, > > > > > > > + &gEfiManagedNetworkProtocolGuid, > > > > > > > + MnpHandle > > > > > > > + ); > > > > > > > + } > > > > > > > + > > > > > > > + return Status; > > > > > > > +} > > > > > > > + > > > > > > > +/** > > > > > > > + Create a child for the service identified by its service > > > > > > > binding > > > > > protocol > > > > > > GUID > > > > > > > + and get from the child the interface of the protocol > > > > > > > identified > > > > > > > by > > > > > its > > > > > > GUID. > > > > > > > + > > > > > > > + @param[in] ControllerHandle Controller handle. > > > > > > > + @param[in] ServiceBindingProtocolGuid Service binding > > > > > > > protocol > > > > > GUID > > > > > > of > > > > > > > the > > > > > > > + service to be > > > > > > > created. > > > > > > > + @param[in] ProtocolGuid GUID of the > > > > > > > protocol to > > > > > > > be > > > > > open. > > > > > > > + @param[out] ChildHandle Address where the > > > > > > > handler > > > > > of the > > > > > > > + created child is > > > > > > > returned. > > > > > NULL is > > > > > > > + returned in case > > > > > > > of > > > > > > > error. > > > > > > > + @param[out] Interface Address where a > > > > > > > pointer > > > > > > > to > > > > > the > > > > > > > + protocol interface > > > > > > > is > > > > > returned in > > > > > > > + case of success. > > > > > > > + > > > > > > > + @return EFI_SUCCESS The child was created and the > > > > > > > protocol > > > > > opened. > > > > > > > + @return Others Either the creation of the child or > > > > > > > the > > > > > opening > > > > > > > + of the protocol failed. > > > > > > > +**/ > > > > > > > +STATIC > > > > > > > +EFI_STATUS > > > > > > > +CreateServiceChildAndOpenProtocol ( > > > > > > > + IN EFI_HANDLE ControllerHandle, > > > > > > > + IN EFI_GUID *ServiceBindingProtocolGuid, > > > > > > > + IN EFI_GUID *ProtocolGuid, > > > > > > > + OUT EFI_HANDLE *ChildHandle, > > > > > > > + OUT VOID **Interface > > > > > > > + ) > > > > > > > +{ > > > > > > > + EFI_STATUS Status; > > > > > > > + > > > > > > > + *ChildHandle = NULL; > > > > > > > + Status = NetLibCreateServiceChild ( > > > > > > > + ControllerHandle, > > > > > > > + gImageHandle, > > > > > > > + ServiceBindingProtocolGuid, > > > > > > > + ChildHandle > > > > > > > + ); > > > > > > > + if (!EFI_ERROR (Status)) { > > > > > > > + Status = gBS->OpenProtocol ( > > > > > > > + *ChildHandle, > > > > > > > + ProtocolGuid, > > > > > > > + Interface, > > > > > > > + gImageHandle, > > > > > > > + ControllerHandle, > > > > > > > + EFI_OPEN_PROTOCOL_GET_PROTOCOL > > > > > > > + ); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + NetLibDestroyServiceChild ( > > > > > > > + ControllerHandle, > > > > > > > + gImageHandle, > > > > > > > + ServiceBindingProtocolGuid, > > > > > > > + *ChildHandle > > > > > > > + ); > > > > > > > + *ChildHandle = NULL; > > > > > > > + } > > > > > > > + } > > > > > > > + > > > > > > > + return Status; > > > > > > > +} > > > > > > > + > > > > > > > +/** > > > > > > > + Close the protocol identified by its GUID on the child > > > > > > > handle of > > > > > the > > > > > > service > > > > > > > + identified by its service binding protocol GUID, then > > > > > > > destroy the > > > > > child > > > > > > > + handle. > > > > > > > + > > > > > > > + @param[in] ControllerHandle Controller handle. > > > > > > > + @param[in] ServiceBindingProtocolGuid Service binding > > > > > > > protocol > > > > > GUID > > > > > > of > > > > > > > the > > > > > > > + service to be > > > > > > > destroyed. > > > > > > > + @param[in] ProtocolGuid GUID of the > > > > > > > protocol to > > > > > > > be > > > > > closed. > > > > > > > + @param[in] ChildHandle Handle of the child > > > > > > > to be > > > > > destroyed. > > > > > > > + > > > > > > > +**/ > > > > > > > +STATIC > > > > > > > +VOID > > > > > > > +CloseProtocolAndDestroyServiceChild ( > > > > > > > + IN EFI_HANDLE ControllerHandle, > > > > > > > + IN EFI_GUID *ServiceBindingProtocolGuid, > > > > > > > + IN EFI_GUID *ProtocolGuid, > > > > > > > + IN EFI_HANDLE ChildHandle > > > > > > > + ) > > > > > > > +{ > > > > > > > + gBS->CloseProtocol ( > > > > > > > + ChildHandle, > > > > > > > + ProtocolGuid, > > > > > > > + gImageHandle, > > > > > > > + ControllerHandle > > > > > > > + ); > > > > > > > + > > > > > > > + NetLibDestroyServiceChild ( > > > > > > > + ControllerHandle, > > > > > > > + gImageHandle, > > > > > > > + ServiceBindingProtocolGuid, > > > > > > > + ChildHandle > > > > > > > + ); > > > > > > > +} > > > > > > > + > > > > > > > +/** > > > > > > > + Wait until operation completes. Completion is indicated by > > > > > > > + setting of an appropriate variable. > > > > > > > + > > > > > > > + @param[in] Context A pointer to the HTTP > > > > > > > download > > > > > context. > > > > > > > + @param[in] CallBackComplete A pointer to the callback > > > > > completion > > > > > > > + variable set by the > > > > > > > callback. > > > > > > > + > > > > > > > + @return EFI_SUCCESS Callback signalled > > > > > > > completion. > > > > > > > + @return EFI_TIMEOUT Timed out waiting for > > > > > > > completion. > > > > > > > + @return Others Error waiting for > > > > > > > completion. > > > > > > > +**/ > > > > > > > +STATIC > > > > > > > +EFI_STATUS > > > > > > > +WaitForCompletion ( > > > > > > > + IN DOWNLOAD_CONTEXT *Context, > > > > > > > + IN OUT BOOLEAN *CallBackComplete > > > > > > > + ) > > > > > > > +{ > > > > > > > + EFI_STATUS Status; > > > > > > > + EFI_EVENT WaitEvt; > > > > > > > + > > > > > > > + Status = EFI_SUCCESS; > > > > > > > + > > > > > > > + // Use a timer to measure timeout. Cannot use Stall here! > > > > > > > + Status = gBS->CreateEvent ( > > > > > > > + EVT_TIMER, > > > > > > > + TPL_CALLBACK, > > > > > > > + NULL, > > > > > > > + NULL, > > > > > > > + &WaitEvt > > > > > > > + ); > > > > > > > + ASSERT_EFI_ERROR (Status); > > > > > > > + > > > > > > > + if (!EFI_ERROR (Status)) { > > > > > > > + Status = gBS->SetTimer( > > > > > > > + WaitEvt, > > > > > > > + TimerRelative, > > > > > > > + EFI_TIMER_PERIOD_SECONDS > > > (TIMER_MAX_TIMEOUT_S) > > > > > > > + ); > > > > > > > + > > > > > > > + ASSERT_EFI_ERROR (Status); > > > > > > > + } > > > > > > > + > > > > > > > + while (! *CallBackComplete && > > > > > > > + (!EFI_ERROR (Status)) && > > > > > > > + EFI_ERROR (gBS->CheckEvent (WaitEvt)) > > > > > > > + ) { > > > > > > > + Status = Context->Http->Poll (Context->Http); > > > > > > > + } > > > > > > > + > > > > > > > + gBS->SetTimer (WaitEvt, TimerCancel, 0); > > > > > > > + gBS->CloseEvent (WaitEvt); > > > > > > > + > > > > > > > + if (*CallBackComplete) { > > > > > > > + return EFI_SUCCESS; > > > > > > > + } > > > > > > > + > > > > > > > + if (!EFI_ERROR (Status)) { > > > > > > > + Status = EFI_TIMEOUT; > > > > > > > + } > > > > > > > + > > > > > > > + return Status; > > > > > > > +} > > > > > > > + > > > > > > > +/** > > > > > > > + Generate and send a request to the http server. > > > > > > > + > > > > > > > + @param[in] Context HTTP download context. > > > > > > > + @param[in] DownloadUrl Fully qualified URL to be > > > > > downloaded. > > > > > > > + > > > > > > > + @return EFI_SUCCESS Request has been sent > > > > > > > successfully. > > > > > > > + @return EFI_INVALID_PARAMETER Invalid URL. > > > > > > > + @return EFI_OUT_OF_RESOURCES Out of memory. > > > > > > > + @return EFI_DEVICE_ERROR If HTTPS is used, this > > > > > > > probably > > > > > > > + means that TLS support > > > > > > > either was > > > > > not > > > > > > > + installed or not configured. > > > > > > > + @return Others Error sending the request. > > > > > > > +**/ > > > > > > > + > > > > > > > +STATIC > > > > > > > +EFI_STATUS > > > > > > > +SendRequest ( > > > > > > > + IN DOWNLOAD_CONTEXT *Context, > > > > > > > + IN CHAR16 *DownloadUrl > > > > > > > + ) > > > > > > > +{ > > > > > > > + EFI_HTTP_REQUEST_DATA RequestData; > > > > > > > + EFI_HTTP_HEADER RequestHeader; > > > > > > > + EFI_HTTP_MESSAGE RequestMessage; > > > > > > > + EFI_STATUS Status; > > > > > > > + > > > > > > > + ZeroMem (&RequestData, sizeof (RequestData)); > > > > > > > + ZeroMem (&RequestHeader, sizeof (RequestHeader)); > > > > > > > + ZeroMem (&RequestMessage, sizeof (RequestMessage)); > > > > > > > + ZeroMem (&Context->RequestToken, sizeof (Context- > > > > > > >RequestToken)); > > > > > > > + > > > > > > > + RequestHeader.FieldName = "Host"; > > > > > > > + if (Context->ProxyServerAddr) { > > > > > > > + RequestHeader.FieldValue = Context->ProxyServerAddr; > > > > > > > + } else { > > > > > > > + CHAR16 *Host; > > > > > > > + UINTN StringSize; > > > > > > > + > > > > > > > + Host = (CHAR16 *)Context->ServerAddrAndProto; > > > > > > > + while (*Host != CHAR_NULL && *Host != L'/') { > > > > > > > + Host++; > > > > > > > + } > > > > > > > + > > > > > > > + if (*Host == CHAR_NULL) { > > > > > > > + return EFI_INVALID_PARAMETER; > > > > > > > + } > > > > > > > + > > > > > > > + // > > > > > > > + // Get the next slash > > > > > > > + // > > > > > > > + Host++; > > > > > > > + // > > > > > > > + // And now the host name > > > > > > > + // > > > > > > > + Host++; > > > > > > > + > > > > > > > + StringSize = StrLen (Host) + 1; > > > > > > > + RequestHeader.FieldValue = AllocatePool (StringSize); > > > > > > > + if (!RequestHeader.FieldValue) { > > > > > > > + return EFI_OUT_OF_RESOURCES; > > > > > > > + } > > > > > > > + > > > > > > > + UnicodeStrToAsciiStrS (Host, > > > > > > > RequestHeader.FieldValue, > > > > > StringSize); > > > > > > > + } > > > > > > > + > > > > > > > + RequestMessage.HeaderCount++; > > > > > > > + > > > > > > > + RequestData.Method = HttpMethodGet; > > > > > > > + RequestData.Url = DownloadUrl; > > > > > > > + > > > > > > > + RequestMessage.Data.Request = &RequestData; > > > > > > > + RequestMessage.Headers = &RequestHeader; > > > > > > > + RequestMessage.BodyLength = 0; > > > > > > > + RequestMessage.Body = NULL; > > > > > > > + Context->RequestToken.Event = NULL; > > > > > > > + > > > > > > > + // > > > > > > > + // Completion callback event to be set when Request > > > > > > > completes. > > > > > > > + // > > > > > > > + Status = gBS->CreateEvent ( > > > > > > > + EVT_NOTIFY_SIGNAL, > > > > > > > + TPL_CALLBACK, > > > > > > > + RequestCallback, > > > > > > > + Context, > > > > > > > + &Context->RequestToken.Event > > > > > > > + ); > > > > > > > + ASSERT_EFI_ERROR (Status); > > > > > > > + > > > > > > > + Context->RequestToken.Status = EFI_SUCCESS; > > > > > > > + Context->RequestToken.Message = &RequestMessage; > > > > > > > + gRequestCallbackComplete = FALSE; > > > > > > > + Status = Context->Http->Request (Context->Http, &Context- > > > > > > >RequestToken); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + Status = WaitForCompletion (Context, > > > > &gRequestCallbackComplete); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + Context->Http->Cancel (Context->Http, &Context- > > > > >RequestToken); > > > > > > > + } > > > > > > > +Error: > > > > > > > + SHELL_FREE_NON_NULL (RequestHeader.FieldValue); > > > > > > > + if (Context->RequestToken.Event) { > > > > > > > + gBS->CloseEvent (Context->RequestToken.Event); > > > > > > > + ZeroMem (&Context->RequestToken, sizeof (Context- > > > > > > >RequestToken)); > > > > > > > + } > > > > > > > + > > > > > > > + return Status; > > > > > > > +} > > > > > > > + > > > > > > > +/** > > > > > > > + Update the progress of a file download > > > > > > > + This procedure is called each time a new HTTP body portion > > > > > > > is > > > > > received. > > > > > > > + > > > > > > > + @param[in] Context HTTP download context. > > > > > > > + @param[in] DownloadLen Portion size, in bytes. > > > > > > > + @param[in] Buffer The pointer to the parsed buffer. > > > > > > > + > > > > > > > + @retval EFI_SUCCESS Portion saved. > > > > > > > + @retval Other Error saving the portion. > > > > > > > + > > > > > > > +**/ > > > > > > > +STATIC > > > > > > > +EFI_STATUS > > > > > > > +EFIAPI > > > > > > > +SavePortion ( > > > > > > > + IN DOWNLOAD_CONTEXT *Context, > > > > > > > + IN UINTN DownloadLen, > > > > > > > + IN CHAR8 *Buffer > > > > > > > + ) > > > > > > > +{ > > > > > > > + CHAR16 Progress[HTTP_PROGRESS_MESSAGE_SIZE]; > > > > > > > + UINTN NbOfKb; > > > > > > > + UINTN Index; > > > > > > > + UINTN LastStep; > > > > > > > + UINTN Step; > > > > > > > + EFI_STATUS Status; > > > > > > > + > > > > > > > + LastStep = 0; > > > > > > > + Step = 0; > > > > > > > + ShellSetFilePosition (mFileHandle, Context- > > > > >LastReportedNbOfBytes); > > > > > > > + Status = ShellWriteFile (mFileHandle, &DownloadLen, > > > > > > > Buffer); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + if (Context->ContentDownloaded > 0) { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF), > > > > > > > mHttpHiiHandle > > > > > > > + ); > > > > > > > + } > > > > > > > + > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_HTTP_ERR_WRITE), > > > > > > > + mHttpHiiHandle, mLocalFilePath, Status > > > > > > > + ); > > > > > > > + > > > > > > > + return Status; > > > > > > > + } > > > > > > > + > > > > > > > + if (Context->ContentDownloaded == 0) { > > > > > > > + ShellPrintEx (-1, -1, L"%s 0 Kb", > > > > > > > HTTP_PROGR_FRAME); > > > > > > > + } > > > > > > > + > > > > > > > + Context->ContentDownloaded += DownloadLen; > > > > > > > + NbOfKb = Context->ContentDownloaded >> 10; > > > > > > > + > > > > > > > + Progress[0] = L'\0'; > > > > > > > + if (Context->ContentLength) { > > > > > > > + LastStep = (Context->LastReportedNbOfBytes * > > > > > > > HTTP_PROGRESS_SLIDER_STEPS) / > > > > > > > + Context->ContentLength; > > > > > > > + Step = (Context->ContentDownloaded * > > > > > > HTTP_PROGRESS_SLIDER_STEPS) > > > > > > > / > > > > > > > + Context->ContentLength; > > > > > > > + } > > > > > > > + > > > > > > > + Context->LastReportedNbOfBytes = Context- > > > >ContentDownloaded; > > > > > > > + > > > > > > > + if (Step <= LastStep) { > > > > > > > + if (!Context->ContentLength) { > > > > > > > + // > > > > > > > + // Update downloaded size, there is no length info > > > > > > > available. > > > > > > > + // > > > > > > > + ShellPrintEx (-1, -1, L"%s", HTTP_KB); > > > > > > > + ShellPrintEx (-1, -1, L"%7d Kb", NbOfKb); > > > > > > > + } > > > > > > > + > > > > > > > + return EFI_SUCCESS; > > > > > > > + } > > > > > > > + > > > > > > > + ShellPrintEx (-1, -1, L"%s", HTTP_PROGRESS_DEL); > > > > > > > + > > > > > > > + Status = StrCpyS (Progress, HTTP_PROGRESS_MESSAGE_SIZE, > > > > > > > HTTP_PROGR_FRAME); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + return Status; > > > > > > > + } > > > > > > > + > > > > > > > + for (Index = 1; Index < Step; Index++) { > > > > > > > + Progress[Index] = L'='; > > > > > > > + } > > > > > > > + > > > > > > > + if (Step) { > > > > > > > + Progress[Step] = L'>'; > > > > > > > + } > > > > > > > + > > > > > > > + UnicodeSPrint ( > > > > > > > + Progress + (sizeof (HTTP_PROGR_FRAME) / sizeof > > > > > > > (CHAR16)) - 1, > > > > > > > + sizeof (Progress) - sizeof (HTTP_PROGR_FRAME), > > > > > > > + L" %7d Kb", > > > > > > > + NbOfKb > > > > > > > + ); > > > > > > > + > > > > > > > + > > > > > > > + ShellPrintEx (-1, -1, L"%s", Progress); > > > > > > > + > > > > > > > + return EFI_SUCCESS; > > > > > > > +} > > > > > > > + > > > > > > > +/** > > > > > > > + Replace the original Host and URI with Host and URI > > > > > > > returned by > > > > > > > the > > > > > > > + HTTP server in 'Location' header (redirection). > > > > > > > + > > > > > > > + @param[in] Location A pointer to the 'Location' > > > > > > > string > > > > > > > + provided by HTTP server. > > > > > > > + @param[in] Context A pointer to HTTP download > > > > > > > context. > > > > > > > + @param[in] DownloadUrl Fully qualified HTTP URL. > > > > > > > + > > > > > > > + @return EFI_SUCCESS Host and URI were > > > > > > > successfully > > > > > > > set. > > > > > > > + @return EFI_OUT_OF_RESOURCES Error setting Host or URI. > > > > > > > +**/ > > > > > > > + > > > > > > > +STATIC > > > > > > > +EFI_STATUS > > > > > > > +SetHostURI ( > > > > > > > + IN CHAR8 *Location, > > > > > > > + IN DOWNLOAD_CONTEXT *Context, > > > > > > > + IN CHAR16 *DownloadUrl > > > > > > > + ) > > > > > > > +{ > > > > > > > + EFI_STATUS Status; > > > > > > > + UINTN StringSize; > > > > > > > + CHAR8 *Tmp; > > > > > > > + CHAR16 *Url; > > > > > > > + > > > > > > > + Tmp = NULL; > > > > > > > + Url = NULL; > > > > > > > + > > > > > > > + StringSize = (AsciiStrSize (Location) * sizeof (CHAR16)); > > > > > > > + Url = AllocateZeroPool (StringSize); > > > > > > > + if (!Url) { > > > > > > > + return EFI_OUT_OF_RESOURCES; > > > > > > > + } > > > > > > > + > > > > > > > + Status = AsciiStrToUnicodeStrS ( > > > > > > > + (CONST CHAR8 *)Location, > > > > > > > + Url, > > > > > > > + StringSize > > > > > > > + ); > > > > > > > + > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + // > > > > > > > + // If an HTTP server redirect to the same location more > > > > > > > than > > > > > > > once, > > > > > > > + // then stop attempts and tell it is not reachable. > > > > > > > + // > > > > > > > + if (!StrCmp (Url, DownloadUrl)) { > > > > > > > + Status = EFI_NO_MAPPING; > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + if (AsciiStrStr (Location, "://")) { > > > > > > > + CHAR8 *Walker; > > > > > > > + UINTN Idx; > > > > > > > + UINTN Step; > > > > > > > + > > > > > > > + Idx = 0; > > > > > > > + Walker = Location; > > > > > > > + > > > > > > > + for (Step = 0; Step < 2; Step++) { > > > > > > > + for (; *Walker != '/' && *Walker != '\0'; Walker++) { > > > > > > > + Idx++; > > > > > > > + } > > > > > > > + if (!Step) { > > > > > > > + // > > > > > > > + // Skip "//" > > > > > > > + // > > > > > > > + Idx += 2; > > > > > > > + Walker += 2; > > > > > > > + } > > > > > > > + } > > > > > > > + > > > > > > > + Tmp = AllocateZeroPool (Idx + 1); > > > > > > > + if (!Tmp) { > > > > > > > + Status = EFI_OUT_OF_RESOURCES; > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + CopyMem (Tmp, Location, Idx); > > > > > > > + > > > > > > > + // > > > > > > > + // Location now points to URI > > > > > > > + // > > > > > > > + Location += Idx; > > > > > > > + StringSize = (Idx + 1) * sizeof (CHAR16); > > > > > > > + > > > > > > > + SHELL_FREE_NON_NULL (Context->ServerAddrAndProto); > > > > > > > + > > > > > > > + Context->ServerAddrAndProto = AllocateZeroPool > > > > > > > (StringSize); > > > > > > > + if (!Context->ServerAddrAndProto) { > > > > > > > + Status = EFI_OUT_OF_RESOURCES; > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + Status = AsciiStrToUnicodeStrS ( > > > > > > > + (CONST CHAR8 *)Tmp, > > > > > > > + Context->ServerAddrAndProto, > > > > > > > + StringSize > > > > > > > + ); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + } > > > > > > > + > > > > > > > + SHELL_FREE_NON_NULL (Context->URI); > > > > > > > + > > > > > > > + StringSize = AsciiStrSize (Location) * sizeof (CHAR16); > > > > > > > + Context->URI = AllocateZeroPool (StringSize); > > > > > > > + if (!Context->URI) { > > > > > > > + Status = EFI_OUT_OF_RESOURCES; > > > > > > > + goto Error; > > > > > > > + } > > > > > > > + > > > > > > > + // > > > > > > > + // Now make changes to the URI part. > > > > > > > + // > > > > > > > + Status = AsciiStrToUnicodeStrS ( > > > > > > > + (CONST CHAR8 *)Location, > > > > > > > + Context->URI, > > > > > > > + StringSize > > > > > > > + ); > > > > > > > +Error: > > > > > > > + SHELL_FREE_NON_NULL (Tmp); > > > > > > > + SHELL_FREE_NON_NULL (Url); > > > > > > > + return Status; > > > > > > > +} > > > > > > > + > > > > > > > +/** > > > > > > > + Message parser callback. > > > > > > > + Save a portion of HTTP body. > > > > > > > + > > > > > > > + @param[in] EventType Type of event. Can be either > > > > > > > + OnComplete or OnData. > > > > > > > + @param[in] Data A pointer to the buffer with > > > > > > > data. > > > > > > > + @param[in] Length Data length of this portion. > > > > > > > + @param[in] Context A pointer to the HTTP download > > > > > context. > > > > > > > + > > > > > > > + @return EFI_SUCCESS The portion was processed > > > > > > > successfully. > > > > > > > + @return Other Error returned by SavePortion. > > > > > > > +**/ > > > > > > > + > > > > > > > +STATIC > > > > > > > +EFI_STATUS > > > > > > > +EFIAPI > > > > > > > +ParseMsg ( > > > > > > > + IN HTTP_BODY_PARSE_EVENT EventType, > > > > > > > + IN CHAR8 *Data, > > > > > > > + IN UINTN Length, > > > > > > > + IN VOID *Context > > > > > > > + ) > > > > > > > +{ > > > > > > > + if (!Data || > > > > > > > + (EventType == BodyParseEventOnComplete) || > > > > > > > + (!Context) > > > > > > > + ) { > > > > > > > + return EFI_SUCCESS; > > > > > > > + } > > > > > > > + > > > > > > > + return SavePortion (Context, Length, Data); > > > > > > > +} > > > > > > > + > > > > > > > + > > > > > > > +/** > > > > > > > + Get HTTP server response and collect the whole body as a > > > > > > > file. > > > > > > > + Set appropriate status in Context (REQ_OK, REQ_REPEAT, > > > > REQ_ERROR). > > > > > > > + Note that even if HTTP server returns an error code, it > > > > > > > might > > > > > > > send > > > > > > > + the body as well. This body will be collected in the > > > > > > > resultant > > > > > file. > > > > > > > + > > > > > > > + @param[in] Context A pointer to the HTTP download > > > > > context. > > > > > > > + @param[in] DownloadedUrl A pointer to the fully > > > > > > > qualified URL > > > > > to > > > > > > > download. > > > > > > > + > > > > > > > + @return EFI_SUCCESS Valid file. Body successfully > > > > > collected. > > > > > > > + @return EFI_HTTP_ERROR Response is a valid HTTP > > > > > > > response, > > > > > > > but > > > > > the > > > > > > > + HTTP server > > > > > > > + indicated an error (HTTP code > > > > > > > >= > > > > > > > 400). > > > > > > > + Response body may contain full > > > > > > > + HTTP server response. > > > > > > > + @return Others Error getting the reponse from > > > > > > > the > > > > > HTTP server. > > > > > > > + Response body is not > > > > > > > collected. > > > > > > > +**/ > > > > > > > +STATIC > > > > > > > +EFI_STATUS > > > > > > > +GetResponse ( > > > > > > > + IN DOWNLOAD_CONTEXT *Context, > > > > > > > + IN CHAR16 *DownloadUrl > > > > > > > + ) > > > > > > > +{ > > > > > > > + EFI_HTTP_RESPONSE_DATA ResponseData; > > > > > > > + EFI_HTTP_MESSAGE ResponseMessage; > > > > > > > + EFI_STATUS Status; > > > > > > > + VOID *MsgParser; > > > > > > > + BOOLEAN IsTrunked; > > > > > > > + > > > > > > > + ZeroMem (&ResponseData, sizeof (ResponseData)); > > > > > > > + ZeroMem (&ResponseMessage, sizeof (ResponseMessage)); > > > > > > > + ZeroMem (&Context->ResponseToken, sizeof (Context- > > > > > > >ResponseToken)); > > > > > > > + IsTrunked = FALSE; > > > > > > > + > > > > > > > + ResponseMessage.Body = Context->Buffer; > > > > > > > + Context->ResponseToken.Status = EFI_SUCCESS; > > > > > > > + Context->ResponseToken.Message = &ResponseMessage; > > > > > > > + Context->ContentLength = 0; > > > > > > > + Context->Status = REQ_OK; > > > > > > > + MsgParser = NULL; > > > > > > > + ResponseData.StatusCode = > > > > HTTP_STATUS_UNSUPPORTED_STATUS; > > > > > > > + ResponseMessage.Data.Response = &ResponseData; > > > > > > > + Context->ResponseToken.Event = NULL; > > > > > > > + > > > > > > > + do { > > > > > > > + SHELL_FREE_NON_NULL (ResponseMessage.Headers); > > > > > > > + ResponseMessage.HeaderCount = 0; > > > > > > > + gResponseCallbackComplete = FALSE; > > > > > > > + ResponseMessage.BodyLength = Context->BufferSize; > > > > > > > + > > > > > > > + if (ShellGetExecutionBreakFlag ()) { > > > > > > > + Status = EFI_ABORTED; > > > > > > > + break; > > > > > > > + } > > > > > > > + > > > > > > > + if (!Context->ContentDownloaded && !Context- > > > > > > >ResponseToken.Event) { > > > > > > > + Status = gBS->CreateEvent ( > > > > > > > + EVT_NOTIFY_SIGNAL, > > > > > > > + TPL_CALLBACK, > > > > > > > + ResponseCallback, > > > > > > > + Context, > > > > > > > + &Context->ResponseToken.Event > > > > > > > + ); > > > > > > > + ASSERT_EFI_ERROR (Status); > > > > > > > + } else { > > > > > > > + ResponseMessage.Data.Response = NULL; > > > > > > > + } > > > > > > > + > > > > > > > + Status = Context->Http->Response (Context->Http, > > > > > > > &Context- > > > > > > > >ResponseToken); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + break; > > > > > > > + } > > > > > > > + > > > > > > > + Status = WaitForCompletion (Context, > > > > > &gResponseCallbackComplete); > > > > > > > + if (EFI_ERROR (Status) && ResponseMessage.HeaderCount) > > > > > > > { > > > > > > > + Status = EFI_SUCCESS; > > > > > > > + } > > > > > > > + > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + Context->Http->Cancel (Context->Http, > > > > > &Context->ResponseToken); > > > > > > > + break; > > > > > > > + } > > > > > > > + > > > > > > > + if (!Context->ContentDownloaded) { > > > > > > > + EFI_HTTP_HEADER *Header; > > > > > > > + BOOLEAN Redirection; > > > > > > > + > > > > > > > + Redirection = > > > > > > > + ((ResponseData.StatusCode >= > > > > > > HTTP_STATUS_300_MULTIPLE_CHOICES) > > > > > > > && > > > > > > > + (ResponseData.StatusCode <= > > > > > > > HTTP_STATUS_307_TEMPORARY_REDIRECT) > > > > > > > + ) || > > > > > > > + (ResponseData.StatusCode == > > > > > > > HTTP_STATUS_308_PERMANENT_REDIRECT); > > > > > > > + > > > > > > > + if (Redirection) { > > > > > > > + // > > > > > > > + // Need to repeat the request with new Location > > > > > > > (server > > > > > redirected). > > > > > > > + // > > > > > > > + Context->Status = REQ_NEED_REPEAT; > > > > > > > + > > > > > > > + Header = HttpFindHeader ( > > > > > > > + ResponseMessage.HeaderCount, > > > > > > > + ResponseMessage.Headers, > > > > > > > + "Location" > > > > > > > + ); > > > > > > > + if (Header) { > > > > > > > + Status = SetHostURI (Header->FieldValue, Context, > > > > > DownloadUrl); > > > > > > > + if (Status == EFI_NO_MAPPING) { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN > > > > > > > (STR_HTTP_ERR_STATUSCODE), > > > > > > > + mHttpHiiHandle, Context->ServerAddrAndProto, > > > > > > > + L"Recursive HTTP server relocation", > > > > > > > + Context->URI > > > > > > > + ); > > > > > > > + } > > > > > > > + } else { > > > > > > > + // > > > > > > > + // Bad reply from the server. Server must specify > > > > > > > the > > > > > location. > > > > > > > + // Indicate that resource was not found, and no > > > > > > > body > > > > > collected. > > > > > > > + // > > > > > > > + Status = EFI_NOT_FOUND; > > > > > > > + } > > > > > > > + > > > > > > > + Context->Http->Cancel (Context->Http, &Context- > > > > > > >ResponseToken); > > > > > > > + > > > > > > > + break; > > > > > > > + } > > > > > > > + > > > > > > > + // > > > > > > > + // Init message-body parser by header information. > > > > > > > + // > > > > > > > + if (!MsgParser) { > > > > > > > + Status = HttpInitMsgParser ( > > > > > > > + ResponseMessage.Data.Request->Method, > > > > > > > + ResponseData.StatusCode, > > > > > > > + ResponseMessage.HeaderCount, > > > > > > > + ResponseMessage.Headers, > > > > > > > + ParseMsg, > > > > > > > + Context, > > > > > > > + &MsgParser > > > > > > > + ); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + break; > > > > > > > + } > > > > > > > + } > > > > > > > + > > > > > > > + // > > > > > > > + // If it is a trunked message, rely on the parser. > > > > > > > + // > > > > > > > + Header = HttpFindHeader ( > > > > > > > + ResponseMessage.HeaderCount, > > > > > > > + ResponseMessage.Headers, > > > > > > > + "Transfer-Encoding" > > > > > > > + ); > > > > > > > + IsTrunked = (Header && > > > > > > > + !AsciiStrCmp (Header->FieldValue, > > > > > > > "chunked") > > > > > > > + ); > > > > > > > + > > > > > > > + HttpGetEntityLength (MsgParser, > > > > > > > &Context->ContentLength); > > > > > > > + > > > > > > > + if (ResponseData.StatusCode >= > > > > HTTP_STATUS_400_BAD_REQUEST > > > > > > && > > > > > > > + (ResponseData.StatusCode != > > > > > > > HTTP_STATUS_308_PERMANENT_REDIRECT) > > > > > > > + ) { > > > > > > > + // > > > > > > > + // Server reported an error via Response code. > > > > > > > + // Collect the body if any. > > > > > > > + // > > > > > > > + if (Context->Status != REQ_ERROR) { > > > > > > > + Context->Status = REQ_ERROR; > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN > > > > > (STR_HTTP_ERR_STATUSCODE), > > > > > > > + mHttpHiiHandle, > > > > > > > Context->ServerAddrAndProto, > > > > > > > + ErrStatusDesc[ResponseData.StatusCode - > > > > > > > + > > > > > > > HTTP_STATUS_400_BAD_REQUEST], > > > > > > > + Context->URI > > > > > > > + ); > > > > > > > + } > > > > > > > + } > > > > > > > + } > > > > > > > + > > > > > > > + // Do NOT try to parse an empty body. > > > > > > > + if (ResponseMessage.BodyLength || IsTrunked) { > > > > > > > + Status = HttpParseMessageBody ( > > > > > > > + MsgParser, > > > > > > > + ResponseMessage.BodyLength, > > > > > > > + ResponseMessage.Body > > > > > > > + ); > > > > > > > + } > > > > > > > + } while (!HttpIsMessageComplete (MsgParser) && > > > > > > > + !EFI_ERROR (Status) && > > > > > > > + ResponseMessage.BodyLength > > > > > > > + ); > > > > > > > + > > > > > > > + SHELL_FREE_NON_NULL (MsgParser); > > > > > > > + if (Context->ResponseToken.Event) { > > > > > > > + gBS->CloseEvent (Context->ResponseToken.Event); > > > > > > > + ZeroMem (&Context->ResponseToken, sizeof (Context- > > > > > > >ResponseToken)); > > > > > > > + } > > > > > > > + > > > > > > > + return Status; > > > > > > > +} > > > > > > > + > > > > > > > +/** > > > > > > > + Worker function that download the data of a file from a > > > > > > > HTTP > > > > > > > server > > > > > > given > > > > > > > + the path of the file and its size. > > > > > > > + > > > > > > > + @param[in] Context A pointer to the HTTP > > > > > > > download > > > > > context. > > > > > > > + > > > > > > > + @retval EFI_SUCCESS The file was downloaded. > > > > > > > + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. > > > > > > > + #retval EFI_HTTP_ERROR The server returned a valid > > > > > > > HTTP > > > > > error. > > > > > > > + Examine the mLocalFilePath > > > > > > > file > > > > > > > + to get error body. > > > > > > > + @retval Others The downloading of the file > > > > > > > from > > > > > > > the > > > > > server > > > > > > > + failed. > > > > > > > + > > > > > > > +**/ > > > > > > > +STATIC > > > > > > > +EFI_STATUS > > > > > > > +DownloadFile ( > > > > > > > + IN DOWNLOAD_CONTEXT *Context > > > > > > > + ) > > > > > > > +{ > > > > > > > + EFI_STATUS Status; > > > > > > > + CHAR16 *DownloadUrl; > > > > > > > + UINTN UrlSize; > > > > > > > + > > > > > > > + ASSERT (Context); > > > > > > > + > > > > > > > + DownloadUrl = NULL; > > > > > > > + > > > > > > > + Context->Buffer = AllocatePool (Context->BufferSize); > > > > > > > + if (!Context->Buffer) { > > > > > > > + Status = EFI_OUT_OF_RESOURCES; > > > > > > > + goto ON_EXIT; > > > > > > > + } > > > > > > > + > > > > > > > + // > > > > > > > + // OPEN FILE > > > > > > > + // > > > > > > > + if (!EFI_ERROR (ShellFileExists (mLocalFilePath))) { > > > > > > > + ShellDeleteFileByName (mLocalFilePath); > > > > > > > + } > > > > > > > + > > > > > > > + Status = ShellOpenFileByName ( > > > > > > > + mLocalFilePath, > > > > > > > + &mFileHandle, > > > > > > > + EFI_FILE_MODE_CREATE | > > > > > > > + EFI_FILE_MODE_WRITE | > > > > > > > + EFI_FILE_MODE_READ, > > > > > > > + 0); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), > > > > > > > + mHttpHiiHandle, HTTP_APP_NAME, mLocalFilePath > > > > > > > + ); > > > > > > > + goto ON_EXIT; > > > > > > > + } > > > > > > > + > > > > > > > + do { > > > > > > > + SHELL_FREE_NON_NULL (DownloadUrl); > > > > > > > + UrlSize = 0; > > > > > > > + DownloadUrl = StrnCatGrow ( > > > > > > > + &DownloadUrl, > > > > > > > + &UrlSize, > > > > > > > + Context->ServerAddrAndProto, > > > > > > > + StrLen (Context->ServerAddrAndProto) > > > > > > > + ); > > > > > > > + if (Context->URI[0] != L'/') { > > > > > > > + DownloadUrl = StrnCatGrow ( > > > > > > > + &DownloadUrl, > > > > > > > + &UrlSize, > > > > > > > + L"/", > > > > > > > + StrLen (Context->ServerAddrAndProto) > > > > > > > + ); > > > > > > > + } > > > > > > > + > > > > > > > + DownloadUrl = StrnCatGrow ( > > > > > > > + &DownloadUrl, > > > > > > > + &UrlSize, > > > > > > > + Context->URI, > > > > > > > + StrLen (Context->URI)); > > > > > > > + > > > > > > > + ShellPrintHiiEx ( > > > > > > > + -1, -1, NULL, STRING_TOKEN (STR_HTTP_DOWNLOADING), > > > > > > > + mHttpHiiHandle, DownloadUrl); > > > > > > > + > > > > > > > + Status = SendRequest (Context, DownloadUrl); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + goto ON_EXIT; > > > > > > > + } > > > > > > > + > > > > > > > + Status = GetResponse (Context, DownloadUrl); > > > > > > > + > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + goto ON_EXIT; > > > > > > > + } > > > > > > > + } while (Context->Status == REQ_NEED_REPEAT); > > > > > > > + > > > > > > > + if (Context->Status == REQ_ERROR) { > > > > > > > + Status = EFI_HTTP_ERROR; > > > > > > > + } > > > > > > > + > > > > > > > +ON_EXIT: > > > > > > > + // > > > > > > > + // CLOSE FILE > > > > > > > + // > > > > > > > + if (mFileHandle) { > > > > > > > + ShellCloseFile (&mFileHandle); > > > > > > > + } > > > > > > > + > > > > > > > + SHELL_FREE_NON_NULL (DownloadUrl); > > > > > > > + SHELL_FREE_NON_NULL (Context->Buffer); > > > > > > > + > > > > > > > + return Status; > > > > > > > +} > > > > > > > + > > > > > > > +/** > > > > > > > + Retrive HII package list from ImageHandle and publish to > > > > > > > HII > > > > > database. > > > > > > > + > > > > > > > + @param ImageHandle The image handle of the > > > > > > > process. > > > > > > > + > > > > > > > + @return HII handle. > > > > > > > +**/ > > > > > > > +EFI_HII_HANDLE > > > > > > > +InitializeHiiPackage ( > > > > > > > + EFI_HANDLE ImageHandle > > > > > > > + ) > > > > > > > +{ > > > > > > > + EFI_STATUS Status; > > > > > > > + EFI_HII_PACKAGE_LIST_HEADER *PackageList; > > > > > > > + EFI_HII_HANDLE HiiHandle; > > > > > > > + > > > > > > > + // > > > > > > > + // Retrieve HII package list from ImageHandle > > > > > > > + // > > > > > > > + Status = gBS->OpenProtocol ( > > > > > > > + ImageHandle, > > > > > > > + &gEfiHiiPackageListProtocolGuid, > > > > > > > + (VOID **)&PackageList, > > > > > > > + ImageHandle, > > > > > > > + NULL, > > > > > > > + EFI_OPEN_PROTOCOL_GET_PROTOCOL > > > > > > > + ); > > > > > > > + ASSERT_EFI_ERROR (Status); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + return NULL; > > > > > > > + } > > > > > > > + > > > > > > > + // > > > > > > > + // Publish HII package list to HII Database. > > > > > > > + // > > > > > > > + Status = gHiiDatabase->NewPackageList ( > > > > > > > + gHiiDatabase, > > > > > > > + PackageList, > > > > > > > + NULL, > > > > > > > + &HiiHandle > > > > > > > + ); > > > > > > > + ASSERT_EFI_ERROR (Status); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + return NULL; > > > > > > > + } > > > > > > > + return HiiHandle; > > > > > > > +} > > > > > > > diff --git > > > a/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.h > > > > > > > b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.h > > > > > > > new file mode 100644 > > > > > > > index 000000000000..daebe9cf1731 > > > > > > > --- /dev/null > > > > > > > +++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.h > > > > > > > @@ -0,0 +1,88 @@ > > > > > > > +/** @file > > > > > > > + Header file for 'http' command functions. > > > > > > > + > > > > > > > + Copyright (c) 2010 - 2017, Intel Corporation. All rights > > > > > > > reserved. > > > > >
> > > > > > > + Copyright (c) 2015, ARM Ltd. All rights reserved.
> > > > > > > + Copyright (c) 2020, Broadcom. All rights reserved.
> > > > > > > + > > > > > > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > > > > > > + > > > > > > > +**/ > > > > > > > + > > > > > > > +#ifndef _HTTP_H_ > > > > > > > +#define _HTTP_H_ > > > > > > > + > > > > > > > +#include > > > > > > > + > > > > > > > +#include > > > > > > > +#include > > > > > > > +#include > > > > > > > +#include > > > > > > > +#include > > > > > > > +#include > > > > > > > +#include > > > > > > > +#include > > > > > > > +#include > > > > > > > +#include > > > > > > > +#include > > > > > > > +#include > > > > > > > +#include > > > > > > > + > > > > > > > +#include > > > > > > > +#include > > > > > > > +#include > > > > > > > + > > > > > > > +#define HTTP_APP_NAME L"http" > > > > > > > + > > > > > > > +extern EFI_HII_HANDLE mHttpHiiHandle; > > > > > > > + > > > > > > > +typedef enum { > > > > > > > + REQ_OK = 0, > > > > > > > + REQ_NEED_REPEAT = 1, > > > > > > > + REQ_ERROR = 2 > > > > > > > +} REQ_STATUS; > > > > > > > + > > > > > > > +typedef struct { > > > > > > > + UINTN ContentDownloaded; > > > > > > > + UINTN ContentLength; > > > > > > > + UINTN LastReportedNbOfBytes; > > > > > > > + UINTN BufferSize; > > > > > > > + REQ_STATUS Status; > > > > > > > + UINT8 *Buffer; > > > > > > > + CHAR8 *ProxyServerAddr; > > > > > > > + CHAR16 *ServerAddrAndProto; > > > > > > > + CHAR16 *URI; > > > > > > > + EFI_HTTP_TOKEN ResponseToken; > > > > > > > + EFI_HTTP_TOKEN RequestToken; > > > > > > > + EFI_HTTP_PROTOCOL *Http; > > > > > > > +} DOWNLOAD_CONTEXT; > > > > > > > + > > > > > > > +/** > > > > > > > + Function for 'http' command. > > > > > > > + > > > > > > > + @param[in] ImageHandle The image handle. > > > > > > > + @param[in] SystemTable The system table. > > > > > > > + > > > > > > > + @retval SHELL_SUCCESS Command completed > > > > > > > successfully. > > > > > > > + @retval SHELL_INVALID_PARAMETER Command usage error. > > > > > > > + @retval SHELL_ABORTED The user aborts the > > > > > > > operation. > > > > > > > + @retval value Unknown error. > > > > > > > +**/ > > > > > > > +SHELL_STATUS > > > > > > > +RunHttp ( > > > > > > > + IN EFI_HANDLE ImageHandle, > > > > > > > + IN EFI_SYSTEM_TABLE *SystemTable > > > > > > > + ); > > > > > > > + > > > > > > > +/** > > > > > > > + Retrive HII package list from ImageHandle and publish to > > > > > > > HII > > > > > database. > > > > > > > + > > > > > > > + @param ImageHandle The image handle of the > > > > > > > process. > > > > > > > + > > > > > > > + @return HII handle. > > > > > > > +**/ > > > > > > > +EFI_HII_HANDLE > > > > > > > +InitializeHiiPackage ( > > > > > > > + EFI_HANDLE ImageHandle > > > > > > > + ); > > > > > > > +#endif // _HTTP_H_ > > > > > > > diff --git > > > > a/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.uni > > > > > > > b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.uni > > > > > > > new file mode 100644 > > > > > > > index 000000000000..ab62ffacb812 > > > > > > > --- /dev/null > > > > > > > +++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.uni > > > > > > > @@ -0,0 +1,95 @@ > > > > > > > +// /** > > > > > > > +// > > > > > > > +// (C) Copyright 2015-2016 Hewlett Packard Enterprise > > > > > > > Development > > > > > > LP
> > > > > > > +// Copyright (c) 2010 - 2018, Intel Corporation. All rights > > > > > > > reserved. > > > > >
> > > > > > > +// Copyright (c) 2020, Broadcom. All rights reserved.
> > > > > > > +// SPDX-License-Identifier: BSD-2-Clause-Patent > > > > > > > +// > > > > > > > +// Module Name: > > > > > > > +// > > > > > > > +// Http.uni > > > > > > > +// > > > > > > > +// Abstract: > > > > > > > +// > > > > > > > +// String definitions for UEFI Shell HTTP command > > > > > > > +// > > > > > > > +// > > > > > > > +// **/ > > > > > > > + > > > > > > > +/=# > > > > > > > + > > > > > > > +#langdef en-US "english" > > > > > > > + > > > > > > > +#string STR_GEN_TOO_MANY #language en-US "%H%s%N: > > > Too > > > > > > many > > > > > > > arguments. Try help http.\r\n" > > > > > > > +#string STR_GEN_TOO_FEW #language en-US "%H%s%N: > > > > > > > Too > > > > few > > > > > > > arguments. Try help http.\r\n" > > > > > > > +#string STR_GEN_PARAM_INV #language en-US "%H%s%N: > > > > Invalid > > > > > > > argument - '%H%s%N'. Try help http.\r\n" > > > > > > > +#string STR_GEN_PROBLEM #language en-US "%H%s%N: > > > > Unknown > > > > > > flag > > > > > > > - '%H%s%N'. Try help http.\r\n" > > > > > > > +#string STR_GEN_FILE_OPEN_FAIL #language en-US "%H%s%N: > > > > Cannot > > > > > > > open file - '%H%s%N'\r\n" > > > > > > > +#string STR_GEN_CRLF #language en-US "\r\n" > > > > > > > + > > > > > > > +#string STR_HTTP_ERR_NO_NIC #language en-US "No > > > > > > > network > > > > > > interface > > > > > > > card found.\r\n" > > > > > > > +#string STR_HTTP_ERR_NIC_NAME #language en-US "Failed to > > > get > > > > the > > > > > > > name of the network interface card number %d - %r\r\n" > > > > > > > +#string STR_HTTP_ERR_OPEN_PROTOCOL #language en-US "Unable > > > > to > > > > > > open > > > > > > > HTTP protocol on '%H%s%N' - %r\r\n" > > > > > > > +#string STR_HTTP_ERR_CONFIGURE #language en-US "Unable to > > > > > > configure > > > > > > > HTTP protocol on '%H%s%N' - %r\r\n" > > > > > > > +#string STR_HTTP_ERR_DOWNLOAD #language en-US "Unable to > > > > > > > download the file '%H%s%N' on '%H%s%N' - %r\r\n" > > > > > > > +#string STR_HTTP_ERR_WRITE #language en-US "Unable to > > > write > > > > > into > > > > > > file > > > > > > > '%H%s%N' - %r\r\n" > > > > > > > +#string STR_HTTP_ERR_NIC_NOT_FOUND #language en-US > > > "Network > > > > > > > Interface Card '%H%s%N' not found.\r\n" > > > > > > > +#string STR_HTTP_ERR_STATUSCODE #language en-US > > > "\r'%H%s%N' > > > > > > reports > > > > > > > '%s' for '%H%s%N' \r\n" > > > > > > > +#string STR_HTTP_DOWNLOADING #language en-US > > > "Downloading > > > > > > > '%H%s%N'\r\n" > > > > > > > + > > > > > > > +#string STR_GET_HELP_HTTP #language en-US "" > > > > > > > +".TH http 0 "Download a file from HTTP server."\r\n" > > > > > > > +".SH NAME\r\n" > > > > > > > +"Download a file from HTTP server.\r\n" > > > > > > > +".SH SYNOPSIS\r\n" > > > > > > > +" \r\n" > > > > > > > +"HTTP [-i interface] [-l ] [-t ]\r\n" > > > > > > > +" host[:port] http_uri [localfilepath]\r\n" > > > > > > > +".SH OPTIONS\r\n" > > > > > > > +" \r\n" > > > > > > > +" -i interface - Specifies an adapter name, i.e., > > > > > > > eth0.\r\n" > > > > > > > +" -l port - Specifies the local port number. > > > > > > > Default > > > > > > > value > > > > > is 0\r\n" > > > > > > > +" and the port number is automatically > > > > > assigned.\r\n" > > > > > > > +" -t - The number of seconds to wait for a > > > > > > > response > > > > > > after\r\n" > > > > > > > +" sending a request packet. Default value > > > > > > > is 0 > > > > > which is > > > > > > > 'automatic'.\r\n" > > > > > > > +" host - Specify HTTP Server IPv4 address.\r\n > > > > > > > + Can be either address or 'http (or > > > > > https)://addr'\r\n > > > > > > > + Can use addresses resolvable by DNS as > > > > > > > well. > > > > > \r\n > > > > > > > + Port can be specified after ':' if > > > > > > > needed. > > > > > > > \r\n > > > > > > > + By default port 80 is used.\r\n" > > > > > > > +" http_uri - HTTP server URI to download the > > > > > > > file.\r\n" > > > > > > > +" localfilepath - Local destination file path.\r\n" > > > > > > > +".SH DESCRIPTION\r\n" > > > > > > > +" \r\n" > > > > > > > +"NOTES:\r\n" > > > > > > > +" 1. The HTTP command allows geting of the file specified by > > > > > > > its > > > > > > > 'http_uri'\r\n" > > > > > > > +" path from the HTTP server specified by its 'host' IPv4 > > > > > > > address. > > > > > If > > > > > > the\r\n" > > > > > > > +" optional 'localfilepath' parameter is provided, the > > > > > > > downloaded > > > > > file > > > > > > is\r\n" > > > > > > > +" stored locally using the provided file path. If the > > > > > > > local > > > > > > > file > > > > > path is\r\n" > > > > > > > +" not specified, the file is stored in the current > > > > > > > directory > > > > > using the > > > > > > file\r\n" > > > > > > > +" server's name.\r\n" > > > > > > > +" 2. Before using the HTTP command, the network interface > > > intended > > > > > to > > > > > > > be\r\n" > > > > > > > +" used to retrieve the file must be configured. This > > > > > configuration may > > > > > > > be\r\n" > > > > > > > +" done by means of the 'ifconfig' command.\r\n" > > > > > > > +" 3. If a network interface is defined with the '-i' option > > > > > > > then > > > > > only > > > > > > this\r\n" > > > > > > > +" interface will be used to retrieve the remote file. > > > > > > > Otherwise, > > > > > all > > > > > > > network\r\n" > > > > > > > +" interfaces are tried in the order they have been > > > > > > > discovered > > > > > during > > > > > > > the\r\n" > > > > > > > +" DXE phase.\r\n" > > > > > > > +".SH EXAMPLES\r\n" > > > > > > > +" \r\n" > > > > > > > +"EXAMPLES:\r\n" > > > > > > > +" * To get the file "dir1/file1.dat" from the HTTP server > > > > > 192.168.1.1, port > > > > > > > 8080, and\r\n" > > > > > > > +" store it as file2.dat in the current directory :\r\n" > > > > > > > +" fs0:\> http 192.168.1.1:8080 dir1/file1.dat > > > > > > > file2.dat\r\n" > > > > > > > +" * To get the file /image.bin via HTTPS from server > > > > > > > 192.168.1.1 > > > > > > > at > > > > > port 443 > > > > > > > \r\n" > > > > > > > +" (default HTTPS port), and store it in the current > > > > > > > directory: > > > > > \r\n" > > > > > > > +" fs0:\> http https://192.168.1.1 image.bin\r\n" > > > > > > > +".SH RETURNVALUES\r\n" > > > > > > > +" \r\n" > > > > > > > +"RETURN VALUES:\r\n" > > > > > > > +" SHELL_SUCCESS The action was completed as > > > > > requested.\r\n" > > > > > > > +" SHELL_INVALID_PARAMETER One of the passed-in parameters > > > was > > > > > > > incorrectly\r\n" > > > > > > > +" formatted or its value was out > > > > > > > of > > > > > bounds.\r\n" > > > > > > > +" SHELL_HTTP_ERROR No EFI errors, but the server > > > > > > > reported > > > > > > > a > > > > > status > > > > > > > code\r\n > > > > > > > + which should be treated as an > > > > > > > error. > > > > > > > If > > > > > an error body > > > > > > > sent\r\n > > > > > > > + by the server, it would be saved > > > > > > > as > > > > > localfilepath > > > > > > parameter." > > > > > > > diff --git > > > > a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.c > > > > > > > b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.c > > > > > > > new file mode 100644 > > > > > > > index 000000000000..7bd5b46d3997 > > > > > > > --- /dev/null > > > > > > > +++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.c > > > > > > > @@ -0,0 +1,53 @@ > > > > > > > +/** @file > > > > > > > + Entrypoint of "http" shell standalone application. > > > > > > > + > > > > > > > + Copyright (c) 2010 - 2017, Intel Corporation. All rights > > > > > > > reserved. > > > > >
> > > > > > > + Copyright (c) 2015, ARM Ltd. All rights reserved.
> > > > > > > + Copyright (c) 2020, Broadcom. All rights reserved.
> > > > > > > + > > > > > > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > > > > > > + > > > > > > > +**/ > > > > > > > +#include "Http.h" > > > > > > > + > > > > > > > +/* > > > > > > > + * String token ID of help message text. > > > > > > > + * Shell supports to find help message in the resource > > > > > > > section of > > > > > > > an > > > > > > > + * application image if * .MAN file is not found. > > > > > > > + * This global variable is added to make build tool > > > > > > > recognizes > > > > > > > + * that the help string is consumed by user and then build > > > > > > > tool > > > > > > > will > > > > > > > + * add the string into the resource section. > > > > > > > + * Thus the application can use '-?' option to show help > > > > > > > message in > > > > > Shell. > > > > > > > + */ > > > > > > > +GLOBAL_REMOVE_IF_UNREFERENCED > > > > > > > +EFI_STRING_ID mStringHelpTokenId = STRING_TOKEN > > > > > > (STR_GET_HELP_HTTP); > > > > > > > + > > > > > > > +/** > > > > > > > + Entry point of Http standalone application. > > > > > > > + > > > > > > > + @param ImageHandle The image handle of the > > > > > > > process. > > > > > > > + @param SystemTable The EFI System Table pointer. > > > > > > > + > > > > > > > + @retval EFI_SUCCESS Http command is executed > > > > > > > sucessfully. > > > > > > > + @retval EFI_ABORTED HII package was failed to > > > > > > > initialize. > > > > > > > + @retval others Other errors when executing > > > > > > > http > > > > > command. > > > > > > > +**/ > > > > > > > +EFI_STATUS > > > > > > > +EFIAPI > > > > > > > +HttpAppInitialize ( > > > > > > > + IN EFI_HANDLE ImageHandle, > > > > > > > + IN EFI_SYSTEM_TABLE *SystemTable > > > > > > > + ) > > > > > > > +{ > > > > > > > + EFI_STATUS Status; > > > > > > > + mHttpHiiHandle = InitializeHiiPackage (ImageHandle); > > > > > > > + if (mHttpHiiHandle == NULL) { > > > > > > > + return EFI_ABORTED; > > > > > > > + } > > > > > > > + > > > > > > > + Status = (EFI_STATUS)RunHttp (ImageHandle, SystemTable); > > > > > > > + > > > > > > > + HiiRemovePackages (mHttpHiiHandle); > > > > > > > + > > > > > > > + return Status; > > > > > > > +} > > > > > > > diff --git > > > > > > a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf > > > > > > > b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf > > > > > > > new file mode 100644 > > > > > > > index 000000000000..d08d47fb37d5 > > > > > > > --- /dev/null > > > > > > > +++ > > > > b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf > > > > > > > @@ -0,0 +1,58 @@ > > > > > > > +## @file > > > > > > > +# Provides Shell 'http' standalone application. > > > > > > > +# > > > > > > > +# Copyright (c) 2010 - 2019, Intel Corporation. All rights > > > > > > > reserved. > > > > >
> > > > > > > +# Copyright (c) 2015, ARM Ltd. All rights reserved.
> > > > > > > +# Copyright (c) 2020, Broadcom. All rights reserved.
> > > > > > > +# > > > > > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > > > > > +# > > > > > > > +# > > > > > > > +## > > > > > > > + > > > > > > > +[Defines] > > > > > > > + INF_VERSION = 0x00010006 > > > > > > > + BASE_NAME = http > > > > > > > + FILE_GUID = > > > > > 56B00FB7-91D2-869B-CE5C-26CD1A89C73C > > > > > > > + MODULE_TYPE = UEFI_APPLICATION > > > > > > > + VERSION_STRING = 1.0 > > > > > > > + ENTRY_POINT = HttpAppInitialize > > > > > > > +# > > > > > > > +# This flag specifies whether HII resource section is > > > > > > > generated > > > > > > > into > > > > > PE > > > > > > image. > > > > > > > +# > > > > > > > + UEFI_HII_RESOURCE_SECTION = TRUE > > > > > > > + > > > > > > > +[Sources.common] > > > > > > > + Http.c > > > > > > > + HttpApp.c > > > > > > > + Http.h > > > > > > > + Http.uni > > > > > > > + > > > > > > > +[Packages] > > > > > > > + EmbeddedPkg/EmbeddedPkg.dec > > > > > > > + MdeModulePkg/MdeModulePkg.dec > > > > > > > + MdePkg/MdePkg.dec > > > > > > > + NetworkPkg/NetworkPkg.dec > > > > > > > + ShellPkg/ShellPkg.dec > > > > > > > + > > > > > > > +[LibraryClasses] > > > > > > > + BaseLib > > > > > > > + BaseMemoryLib > > > > > > > + DebugLib > > > > > > > + FileHandleLib > > > > > > > + HiiLib > > > > > > > + HttpLib > > > > > > > + MemoryAllocationLib > > > > > > > + NetLib > > > > > > > + ShellLib > > > > > > > + UefiApplicationEntryPoint > > > > > > > + UefiBootServicesTableLib > > > > > > > + UefiHiiServicesLib > > > > > > > + UefiLib > > > > > > > + UefiRuntimeServicesTableLib > > > > > > > + > > > > > > > +[Protocols] > > > > > > > + gEfiHiiPackageListProtocolGuid ## CONSUMES > > > > > > > + gEfiHttpProtocolGuid ## CONSUMES > > > > > > > + gEfiHttpServiceBindingProtocolGuid ## CONSUMES > > > > > > > + gEfiManagedNetworkServiceBindingProtocolGuid ## CONSUMES > > > > > > > diff --git > > > > > > > > > > > > > > > > > > > > a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicComma > > > > > > nd. > > > > > > > c > > > > > > > > > > > > > > > > > > > > b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicComma > > > > > > nd. > > > > > > > c > > > > > > > new file mode 100644 > > > > > > > index 000000000000..ba654749a075 > > > > > > > --- /dev/null > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicComma > > > > > > nd. > > > > > > > c > > > > > > > @@ -0,0 +1,134 @@ > > > > > > > +/** @file > > > > > > > + Produce "http" shell dynamic command. > > > > > > > + > > > > > > > + Copyright (c) 2010 - 2017, Intel Corporation. All rights > > > > > > > reserved. > > > > >
> > > > > > > + Copyright (c) 2015, ARM Ltd. All rights reserved.
> > > > > > > + Copyright (c) 2020, Broadcom. All rights reserved.
> > > > > > > + > > > > > > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > > > > > > + > > > > > > > +**/ > > > > > > > +#include > > > > > > > +#include "Http.h" > > > > > > > + > > > > > > > +/** > > > > > > > + This is the shell command handler function pointer callback > > > > > > > type. > > > > > This > > > > > > > + function handles the command when it is invoked in the > > > > > > > shell. > > > > > > > + > > > > > > > + @param[in] This The instance of the > > > > > > > + > > > > > > > EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. > > > > > > > + @param[in] SystemTable The pointer to the system > > > > > > > table. > > > > > > > + @param[in] ShellParameters The parameters associated > > > > > > > with the > > > > > > > command. > > > > > > > + @param[in] Shell The instance of the shell > > > > > > > protocol > > > > > used in > > > > > > > + the context of processing > > > > > > > this > > > > > command. > > > > > > > + > > > > > > > + @return EFI_SUCCESS the operation was sucessful > > > > > > > + @return other the operation failed. > > > > > > > +**/ > > > > > > > +SHELL_STATUS > > > > > > > +EFIAPI > > > > > > > +HttpCommandHandler ( > > > > > > > + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, > > > > > > > + IN EFI_SYSTEM_TABLE *SystemTable, > > > > > > > + IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters, > > > > > > > + IN EFI_SHELL_PROTOCOL *Shell > > > > > > > + ) > > > > > > > +{ > > > > > > > + gEfiShellParametersProtocol = ShellParameters; > > > > > > > + gEfiShellProtocol = Shell; > > > > > > > + > > > > > > > + return RunHttp (gImageHandle, SystemTable); > > > > > > > +} > > > > > > > + > > > > > > > +/** > > > > > > > + This is the command help handler function pointer callback > > > > > > > type. > > > > > This > > > > > > > + function is responsible for displaying help information for > > > > > > > the > > > > > associated > > > > > > > + command. > > > > > > > + > > > > > > > + @param[in] This The instance of the > > > > > > > EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. > > > > > > > + @param[in] Language The pointer to the language string > > > > > > > to use. > > > > > > > + > > > > > > > + @return string Pool allocated help string, must be > > > > > > > freed > > > > > > > by > > > > > caller > > > > > > > +**/ > > > > > > > +CHAR16 * > > > > > > > +EFIAPI > > > > > > > +HttpCommandGetHelp ( > > > > > > > + IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, > > > > > > > + IN CONST CHAR8 *Language > > > > > > > + ) > > > > > > > +{ > > > > > > > + return HiiGetString(mHttpHiiHandle, > > > > > > > + STRING_TOKEN (STR_GET_HELP_HTTP), > > > > > > > + Language); > > > > > > > +} > > > > > > > + > > > > > > > +EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL > > > > mHttpDynamicCommand > > > > > > = { > > > > > > > + HTTP_APP_NAME, > > > > > > > + HttpCommandHandler, > > > > > > > + HttpCommandGetHelp > > > > > > > +}; > > > > > > > + > > > > > > > +/** > > > > > > > + Entry point of Http Dynamic Command. > > > > > > > + > > > > > > > + Produce the DynamicCommand protocol to handle "http" > > > command. > > > > > > > + > > > > > > > + @param ImageHandle The image handle of the > > > > > > > process. > > > > > > > + @param SystemTable The EFI System Table pointer. > > > > > > > + > > > > > > > + @retval EFI_SUCCESS Http command is executed > > > > > > > sucessfully. > > > > > > > + @retval EFI_ABORTED HII package was failed to > > > > > > > initialize. > > > > > > > + @retval others Other errors when executing > > > > > > > http > > > > > command. > > > > > > > +**/ > > > > > > > +EFI_STATUS > > > > > > > +EFIAPI > > > > > > > +HttpCommandInitialize ( > > > > > > > + IN EFI_HANDLE ImageHandle, > > > > > > > + IN EFI_SYSTEM_TABLE *SystemTable > > > > > > > + ) > > > > > > > +{ > > > > > > > + EFI_STATUS Status; > > > > > > > + > > > > > > > + mHttpHiiHandle = InitializeHiiPackage (ImageHandle); > > > > > > > + if (mHttpHiiHandle == NULL) { > > > > > > > + return EFI_ABORTED; > > > > > > > + } > > > > > > > + > > > > > > > + Status = gBS->InstallProtocolInterface ( > > > > > > > + &ImageHandle, > > > > > > > + &gEfiShellDynamicCommandProtocolGuid, > > > > > > > + EFI_NATIVE_INTERFACE, > > > > > > > + &mHttpDynamicCommand > > > > > > > + ); > > > > > > > + ASSERT_EFI_ERROR (Status); > > > > > > > + return Status; > > > > > > > +} > > > > > > > + > > > > > > > +/** > > > > > > > + Http driver unload handler. > > > > > > > + > > > > > > > + @param ImageHandle The image handle of the > > > > > > > process. > > > > > > > + > > > > > > > + @retval EFI_SUCCESS The image is unloaded. > > > > > > > + @retval Others Failed to unload the image. > > > > > > > +**/ > > > > > > > +EFI_STATUS > > > > > > > +EFIAPI > > > > > > > +HttpUnload ( > > > > > > > + IN EFI_HANDLE ImageHandle > > > > > > > +) > > > > > > > +{ > > > > > > > + EFI_STATUS Status; > > > > > > > + Status = gBS->UninstallProtocolInterface ( > > > > > > > + ImageHandle, > > > > > > > + &gEfiShellDynamicCommandProtocolGuid, > > > > > > > + &mHttpDynamicCommand > > > > > > > + ); > > > > > > > + if (EFI_ERROR (Status)) { > > > > > > > + return Status; > > > > > > > + } > > > > > > > + > > > > > > > + HiiRemovePackages (mHttpHiiHandle); > > > > > > > + > > > > > > > + return EFI_SUCCESS; > > > > > > > +} > > > > > > > diff --git > > > > > > > > > > > > > > > > > > > > a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicComma > > > > > > nd. > > > > > > > inf > > > > > > > > > > > > > > > > > > > > b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicComma > > > > > > nd. > > > > > > > inf > > > > > > > new file mode 100644 > > > > > > > index 000000000000..5d46ee2384d5 > > > > > > > --- /dev/null > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicComma > > > > > > nd. > > > > > > > inf > > > > > > > @@ -0,0 +1,63 @@ > > > > > > > +## @file > > > > > > > +# Provides Shell 'http' dynamic command. > > > > > > > +# > > > > > > > +# Copyright (c) 2010 - 2019, Intel Corporation. All rights > > > > > > > reserved. > > > > >
> > > > > > > +# Copyright (c) 2015, ARM Ltd. All rights reserved.
> > > > > > > +# Copyright (c) 2020, Broadcom. All rights reserved.
> > > > > > > +# > > > > > > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > > > > > > +# > > > > > > > +# > > > > > > > +## > > > > > > > + > > > > > > > +[Defines] > > > > > > > + INF_VERSION = 0x00010006 > > > > > > > + BASE_NAME = httpDynamicCommand > > > > > > > + FILE_GUID = > > > > > 19618BCE-55AE-09C6-37E9-4CE04084C7A1 > > > > > > > + MODULE_TYPE = DXE_DRIVER > > > > > > > + VERSION_STRING = 1.0 > > > > > > > + ENTRY_POINT = HttpCommandInitialize > > > > > > > + UNLOAD_IMAGE = HttpUnload > > > > > > > +# > > > > > > > +# This flag specifies whether HII resource section is > > > > > > > generated > > > > > > > into > > > > > PE > > > > > > image. > > > > > > > +# > > > > > > > + UEFI_HII_RESOURCE_SECTION = TRUE > > > > > > > + > > > > > > > +[Sources.common] > > > > > > > + Http.c > > > > > > > + HttpDynamicCommand.c > > > > > > > + Http.h > > > > > > > + Http.uni > > > > > > > + > > > > > > > +[Packages] > > > > > > > + EmbeddedPkg/EmbeddedPkg.dec > > > > > > > + MdePkg/MdePkg.dec > > > > > > > + MdeModulePkg/MdeModulePkg.dec > > > > > > > + NetworkPkg/NetworkPkg.dec > > > > > > > + ShellPkg/ShellPkg.dec > > > > > > > + > > > > > > > +[LibraryClasses] > > > > > > > + BaseLib > > > > > > > + BaseMemoryLib > > > > > > > + DebugLib > > > > > > > + FileHandleLib > > > > > > > + HiiLib > > > > > > > + HttpLib > > > > > > > + MemoryAllocationLib > > > > > > > + NetLib > > > > > > > + ShellLib > > > > > > > + UefiBootServicesTableLib > > > > > > > + UefiDriverEntryPoint > > > > > > > + UefiHiiServicesLib > > > > > > > + UefiLib > > > > > > > + UefiRuntimeServicesTableLib > > > > > > > + > > > > > > > +[Protocols] > > > > > > > + gEfiHiiPackageListProtocolGuid ## CONSUMES > > > > > > > + gEfiHttpProtocolGuid ## CONSUMES > > > > > > > + gEfiHttpServiceBindingProtocolGuid ## CONSUMES > > > > > > > + gEfiManagedNetworkServiceBindingProtocolGuid ## CONSUMES > > > > > > > + gEfiShellDynamicCommandProtocolGuid ## PRODUCES > > > > > > > + > > > > > > > +[DEPEX] > > > > > > > + TRUE > > > > > > > diff --git a/ShellPkg/Include/Guid/ShellLibHiiGuid.h > > > > > > > b/ShellPkg/Include/Guid/ShellLibHiiGuid.h > > > > > > > index 5da9128333a4..d5f2ceac07a9 100644 > > > > > > > --- a/ShellPkg/Include/Guid/ShellLibHiiGuid.h > > > > > > > +++ b/ShellPkg/Include/Guid/ShellLibHiiGuid.h > > > > > > > @@ -58,7 +58,11 @@ > > > > > > > { \ > > > > > > > 0x738a9314, 0x82c1, 0x4592, { 0x8f, 0xf7, 0xc1, 0xbd, > > > > > > > 0xf1, > > > > > > > 0xb2, > > > > > 0x0e, > > > > > > 0xd4 > > > > > > > } \ > > > > > > > } > > > > > > > - > > > > > > > + > > > > > > > +#define SHELL_HTTP_HII_GUID \ > > > > > > > + { \ > > > > > > > + 0x390f84b3, 0x221c, 0x4d9e, { 0xb5, 0x06, 0x6d, 0xb9, > > > > > > > 0x42, > > > > > > > 0x3e, > > > > > 0x0a, > > > > > > > 0x7e } \ > > > > > > > + } > > > > > > > > > > > > > > #define SHELL_BCFG_HII_GUID \ > > > > > > > { \ > > > > > > > @@ -75,6 +79,7 @@ extern EFI_GUID gShellLevel3HiiGuid; > > > > > > > extern EFI_GUID gShellNetwork1HiiGuid; > > > > > > > extern EFI_GUID gShellNetwork2HiiGuid; > > > > > > > extern EFI_GUID gShellTftpHiiGuid; > > > > > > > +extern EFI_GUID gShellHttpHiiGuid; > > > > > > > extern EFI_GUID gShellBcfgHiiGuid; > > > > > > > > > > > > > > #endif > > > > > > > diff --git a/ShellPkg/ShellPkg.dec b/ShellPkg/ShellPkg.dec > > > > > > > index c17e358d15ed..f80a2962dfd1 100644 > > > > > > > --- a/ShellPkg/ShellPkg.dec > > > > > > > +++ b/ShellPkg/ShellPkg.dec > > > > > > > @@ -50,6 +50,7 @@ [Guids] > > > > > > > gShellNetwork1HiiGuid = {0xf3d301bb, 0xf4a5, > > > > > > > 0x45a8, > > > > > {0xb0, 0xb7, > > > > > > > 0xfa, 0x99, 0x9c, 0x62, 0x37, 0xae}} > > > > > > > gShellNetwork2HiiGuid = {0x174b2b5, 0xf505, > > > > > > > 0x4b12, > > > > > {0xaa, 0x60, > > > > > > > 0x59, 0xdf, 0xf8, 0xd6, 0xea, 0x37}} > > > > > > > gShellTftpHiiGuid = {0x738a9314, 0x82c1, > > > > > > > 0x4592, > > > > > {0x8f, 0xf7, 0xc1, > > > > > > > 0xbd, 0xf1, 0xb2, 0x0e, 0xd4}} > > > > > > > + gShellHttpHiiGuid = {0x390f84b3, 0x221c, > > > > > > > 0x4d9e, > > > > > {0xb5, 0x06, > > > > > > 0x6d, > > > > > > > 0xb9, 0x42, 0x3e, 0x0a, 0x7e}} > > > > > > > gShellBcfgHiiGuid = {0x5f5f605d, 0x1583, > > > > > > > 0x4a2d, > > > > > {0xa6, 0xb2, 0xeb, > > > > > > > 0x12, 0xda, 0xb4, 0xa2, 0xb6}} > > > > > > > gShellAcpiViewHiiGuid = {0xda8ccdf4, 0xed8f, > > > > > > > 0x4ffc, > > > > > {0xb5, 0xef, > > > > > > 0x2e, > > > > > > > 0xf5, 0x5e, 0x24, 0x93, 0x2a}} > > > > > > > # FILE_GUID as defined in > > > > > > > ShellPkg/Application/Shell/Shell.inf > > > > > > > diff --git a/ShellPkg/ShellPkg.dsc b/ShellPkg/ShellPkg.dsc > > > > > > > index 91493400cab7..aee00245185d 100644 > > > > > > > --- a/ShellPkg/ShellPkg.dsc > > > > > > > +++ b/ShellPkg/ShellPkg.dsc > > > > > > > @@ -137,6 +137,11 @@ [Components] > > > > > > > > > > > > > > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE > > > > > > > } > > > > > > > ShellPkg/DynamicCommand/TftpDynamicCommand/TftpApp.inf > > > > > > > + > > > > > > > > > > > > > > > > > > > > ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand > > > > > > .in > > > > > > > f { > > > > > > > + > > > > > > > + > > > > > > > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE > > > > > > > + } > > > > > > > + ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf > > > > > > > > > > > > > > > > > > > > ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf > > > > > > > { > > > > > > > > > > > > > > > > > > > > > gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE > > > > > > > -- > > > > > > > 2.17.1 > > > > > > > > > > > > > > > > > > > > > > > > > > > >