From: Ruiyu Ni <ruiyu.ni@intel.com>
To: edk2-devel@lists.01.org
Cc: Jaben Carsey <jaben.carsey@intel.com>,
Chen A Chen <chen.a.chen@intel.com>
Subject: [PATCH 5/5] ShellPkg/dh: Support dump from GUID and "decode" parameter
Date: Mon, 9 Jan 2017 17:30:52 +0800 [thread overview]
Message-ID: <20170109093052.140504-6-ruiyu.ni@intel.com> (raw)
In-Reply-To: <20170109093052.140504-1-ruiyu.ni@intel.com>
To follow Shell spec 2.2, change "dh" to support dump from
protocol GUID and support "decode" parameter to dump the
GUID/name mapping.
Contributed-under: TianoCore Contribution Agreement 1.0
Cc: Jaben Carsey <jaben.carsey@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Signed-off-by: Chen A Chen <chen.a.chen@intel.com>
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
---
ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c | 367 ++++++++++++++++-----
.../UefiShellDriver1CommandsLib.uni | 9 +-
2 files changed, 292 insertions(+), 84 deletions(-)
diff --git a/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c b/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c
index 2773842..d17a29d 100644
--- a/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c
+++ b/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c
@@ -41,6 +41,137 @@ STATIC CONST EFI_GUID *UefiDriverModelProtocolsGuidArray[] = {
NULL
};
+UINTN mGuidDataLen[] = {8, 4, 4, 4, 12};
+/**
+ Function to determine if the string can convert to a GUID.
+ The string must be restricted as "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" format.
+
+ @param[in] String The string to test.
+
+ @retval TRUE The string can convert to a GUID.
+ @retval FALSE The string can't convert to a GUID.
+**/
+BOOLEAN
+IsValidGuidString(
+ IN CONST CHAR16 *String
+ )
+{
+ CONST CHAR16 *Walker;
+ CONST CHAR16 *PrevWalker;
+ UINTN Index;
+
+ if (String == NULL) {
+ return FALSE;
+ }
+
+ Walker = String;
+ PrevWalker = String;
+ Index = 0;
+
+ while (Walker != NULL && *Walker != CHAR_NULL) {
+ if ( (*Walker >= '0' && *Walker <= '9') ||
+ (*Walker >= 'a' && *Walker <= 'f') ||
+ (*Walker >= 'A' && *Walker <= 'F')
+ ) {
+ Walker++;
+ } else {
+ if (*Walker == L'-' && (UINTN)(Walker - PrevWalker) == mGuidDataLen[Index]) {
+ Walker++;
+ PrevWalker = Walker;
+ Index++;
+ } else {
+ return FALSE;
+ }
+ }
+ }
+
+ if ((UINTN)(Walker - PrevWalker) == mGuidDataLen[Index]) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Convert a hex-character to decimal value.
+
+ This internal function only deal with Unicode character
+ which maps to a valid hexadecimal ASII character, i.e.
+ L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
+ Unicode character, the value returned does not make sense.
+
+ @param[in] Char The character to convert.
+
+ @retval The numerical value converted.
+**/
+UINTN
+HexCharToDecimal(
+ IN CHAR16 Char
+ )
+{
+ if (Char >= '0' && Char <= '9') {
+ return Char - L'0';
+ } else if (Char >= 'a' && Char <= 'f') {
+ return Char - L'a' + 10;
+ } else {
+ return Char - L'A' + 10;
+ }
+}
+
+/**
+ Function try to convert a string to GUID format.
+
+ @param[in] String The string will be converted.
+ @param[out] Guid Save the result convert from string.
+
+ @retval EFI_SUCCESS The string was successfully converted to a GUID.
+ @retval EFI_UNSUPPORTED The input string is not in registry format.
+**/
+EFI_STATUS
+ConvertStrToGuid(
+ IN CONST CHAR16 *String,
+ OUT GUID *Guid
+ )
+{
+ CONST CHAR16 *Walker;
+ UINT8 TempValue;
+ UINTN Index;
+
+ if (String == NULL || !IsValidGuidString (String)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Index = 0;
+
+ Walker = String;
+ Guid->Data1 = (UINT32)StrHexToUint64 (Walker);
+
+ Walker += 9;
+ Guid->Data2 = (UINT16)StrHexToUint64 (Walker);
+
+ Walker += 5;
+ Guid->Data3 = (UINT16)StrHexToUint64 (Walker);
+
+ Walker += 5;
+ while (Walker != NULL && *Walker != CHAR_NULL) {
+ if (*Walker == L'-') {
+ Walker++;
+ } else {
+ TempValue = (UINT8)HexCharToDecimal (*Walker);
+ TempValue = (UINT8)LShiftU64 (TempValue, 4);
+ Walker++;
+
+ TempValue += (UINT8)HexCharToDecimal (*Walker);
+ Walker++;
+
+ Guid->Data4[Index] = TempValue;
+ Index++;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
/**
Get the name of a driver by it's handle.
@@ -733,8 +864,7 @@ DoDhForHandleList(
SHELL_STATUS ShellStatus;
ShellStatus = SHELL_SUCCESS;
-
- for ( HandleWalker = HandleList; HandleWalker != NULL && *HandleWalker != NULL; HandleWalker++ ) {
+ for (HandleWalker = HandleList; HandleWalker != NULL && *HandleWalker != NULL; HandleWalker++) {
DoDhByHandle (*HandleWalker, Verbose, Sfo, Language, DriverInfo, TRUE);
if (ShellGetExecutionBreakFlag ()) {
ShellStatus = SHELL_ABORTED;
@@ -745,89 +875,166 @@ DoDhForHandleList(
}
/**
- Display information for all handles.
+ Display information for a GUID of protocol.
- @param[in] Sfo TRUE to output in standard format output (spec).
+ @param[in] Guid The pointer to the name of the protocol.
@param[in] Verbose TRUE for extra info, FALSE otherwise.
+ @param[in] Sfo TRUE to output in standard format output (spec).
@param[in] Language Language string per UEFI specification.
@param[in] DriverInfo TRUE to show all info about the handle.
@retval SHELL_SUCCESS The operation was successful.
+ @retval SHELL_NOT_FOUND The GUID was not found.
@retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
**/
SHELL_STATUS
-DoDhForAll(
- IN CONST BOOLEAN Sfo,
+DoDhByProtocolGuid(
+ IN CONST GUID *Guid,
IN CONST BOOLEAN Verbose,
+ IN CONST BOOLEAN Sfo,
IN CONST CHAR8 *Language,
IN CONST BOOLEAN DriverInfo
)
{
- EFI_HANDLE *HandleList;
+ CHAR16 *Name;
SHELL_STATUS ShellStatus;
+ EFI_HANDLE *HandleList;
- HandleList = GetHandleListByProtocol(NULL);
-
- ShellStatus = DoDhForHandleList(
- HandleList,
- Verbose,
- Sfo,
- Language,
- DriverInfo);
-
- FreePool(HandleList);
+ if (!Sfo) {
+ if (Guid == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_ALL_HEADER), gShellDriver1HiiHandle);
+ } else {
+ Name = GetStringNameFromGuid (Guid, NULL);
+ if (Name == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_GUID_HEADER), gShellDriver1HiiHandle, Guid);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_NAME_HEADER), gShellDriver1HiiHandle, Name);
+ }
+ }
+ }
+ HandleList = GetHandleListByProtocol(Guid);
+ ShellStatus = DoDhForHandleList(HandleList, Verbose, Sfo, Language, DriverInfo);
+ SHELL_FREE_NON_NULL(HandleList);
- return (ShellStatus);
+ return ShellStatus;
}
/**
- Display information for all handles which have a specific protocol.
+ Function to determine use which method to print information.
+ If Protocol is NULL, The function will print all information.
- @param[in] ProtocolName The pointer to the name of the protocol.
+ @param[in] Protocol The pointer to the name or GUID of protocol or NULL.
@param[in] Verbose TRUE for extra info, FALSE otherwise.
@param[in] Sfo TRUE to output in standard format output (spec).
@param[in] Language Language string per UEFI specification.
@param[in] DriverInfo TRUE to show all info about the handle.
- @retval SHELL_SUCCESS The operation was successful.
- @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
+ @retval SHELL_SUCCESS The operation was successful.
+ @retval SHELL_NOT_FOUND The protocol was not found.
+ @retval SHELL_INVALID_PARAMETER Protocol is invalid parameter.
**/
SHELL_STATUS
-DoDhByProtocol(
- IN CONST CHAR16 *ProtocolName,
+DoDhByProtocol (
+ IN CONST CHAR16 *Protocol,
IN CONST BOOLEAN Verbose,
IN CONST BOOLEAN Sfo,
IN CONST CHAR8 *Language,
IN CONST BOOLEAN DriverInfo
)
{
- EFI_GUID *Guid;
+ EFI_GUID Guid;
+ EFI_GUID *GuidPtr;
EFI_STATUS Status;
- EFI_HANDLE *HandleList;
- SHELL_STATUS ShellStatus;
- if (ProtocolName == NULL) {
- return (SHELL_INVALID_PARAMETER);
- }
+ if (Protocol == NULL) {
+ return DoDhByProtocolGuid (NULL, Verbose, Sfo, Language, DriverInfo);
+ } else {
+ Status = ConvertStrToGuid (Protocol, &Guid);
+ if (!EFI_ERROR (Status)) {
+ GuidPtr = &Guid;
+ } else {
+ //
+ // Protocol is a Name, convert it to GUID
+ //
+ Status = GetGuidFromStringName (Protocol, Language, &GuidPtr);
+ if (EFI_ERROR(Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_NAME_FOUND), gShellDriver1HiiHandle, Protocol);
+ return (SHELL_NOT_FOUND);
+ }
+ }
- Status = GetGuidFromStringName(ProtocolName, Language, &Guid);
- if (EFI_ERROR(Status)) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, ProtocolName);
- return (SHELL_INVALID_PARAMETER);
+ return DoDhByProtocolGuid (GuidPtr, Verbose, Sfo, Language, DriverInfo);
}
+}
- HandleList = GetHandleListByProtocol(Guid);
+/**
+ Function to display decode information by Protocol.
+ The parameter Protocol is either a GUID or the name of protocol.
+ If the parameter Protocol is NULL, the function will print all
+ decode information.
- ShellStatus = DoDhForHandleList(
- HandleList,
- Verbose,
- Sfo,
- Language,
- DriverInfo);
+ @param[in] Protocol The pointer to the name or GUID of protocol.
+ @param[in] Language Language string per UEFI specification.
- SHELL_FREE_NON_NULL(HandleList);
+ @retval SHELL_SUCCESS The operation was successful.
+ @retval SHELL_OUT_OT_RESOURCES A memory allocation failed.
+**/
+SHELL_STATUS
+DoDecodeByProtocol(
+ IN CONST CHAR16 *Protocol,
+ IN CONST CHAR8 *Language
+ )
+{
+ EFI_STATUS Status;
+ EFI_GUID *Guids;
+ EFI_GUID Guid;
+ UINTN Counts;
+ UINTN Index;
+ CHAR16 *Name;
+
+ if (Protocol == NULL) {
+ Counts = 0;
+ Status = GetAllMappingGuids (NULL, &Counts);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Guids = AllocatePool (Counts * sizeof(EFI_GUID));
+ if (Guids == NULL) {
+ return SHELL_OUT_OF_RESOURCES;
+ }
- return (ShellStatus);
+ Status = GetAllMappingGuids (Guids, &Counts);
+ if (Status == EFI_SUCCESS) {
+ for (Index = 0; Index < Counts; Index++) {
+ Name = GetStringNameFromGuid (&Guids[Index], Language);
+ if (Name != NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Name, &Guids[Index]);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, &Guids[Index]);
+ }
+ SHELL_FREE_NON_NULL (Name);
+ }
+ }
+ FreePool (Guids);
+ }
+ } else {
+ if (ConvertStrToGuid (Protocol, &Guid) == EFI_SUCCESS) {
+ Name = GetStringNameFromGuid (&Guid, Language);
+ if (Name != NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Name, &Guid);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, &Guid);
+ }
+ SHELL_FREE_NON_NULL(Name);
+ } else {
+ Status = GetGuidFromStringName (Protocol, Language, &Guids);
+ if (Status == EFI_SUCCESS) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Protocol, Guids);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_NAME_FOUND), gShellDriver1HiiHandle, Protocol);
+ }
+ }
+ }
+
+ return SHELL_SUCCESS;
}
/**
@@ -850,10 +1057,12 @@ ShellCommandRunDh (
CHAR8 *Language;
CONST CHAR16 *Lang;
CONST CHAR16 *RawValue;
+ CONST CHAR16 *ProtocolVal;
BOOLEAN SfoFlag;
BOOLEAN DriverFlag;
BOOLEAN VerboseFlag;
UINT64 Intermediate;
+ EFI_HANDLE Handle;
ShellStatus = SHELL_SUCCESS;
Status = EFI_SUCCESS;
@@ -906,60 +1115,54 @@ ShellCommandRunDh (
SfoFlag = ShellCommandLineGetFlag (Package, L"-sfo");
DriverFlag = ShellCommandLineGetFlag (Package, L"-d");
VerboseFlag = (BOOLEAN)(ShellCommandLineGetFlag (Package, L"-v") || ShellCommandLineGetFlag (Package, L"-verbose"));
+ RawValue = ShellCommandLineGetRawValue (Package, 1);
+ ProtocolVal = ShellCommandLineGetValue (Package, L"-p");
- if (ShellCommandLineGetFlag (Package, L"-p")) {
- if (ShellCommandLineGetCount (Package) > 1) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");
- ShellStatus = SHELL_INVALID_PARAMETER;
- } else if (ShellCommandLineGetValue(Package, L"-p") == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-p");
+ if (RawValue == NULL) {
+ if (ShellCommandLineGetFlag (Package, L"-p") && (ProtocolVal == NULL)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-p");
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
//
- // print by protocol
+ // Print information by protocol, The ProtocolVal maybe is name or GUID or NULL.
//
- ShellStatus = DoDhByProtocol(
- ShellCommandLineGetValue(Package, L"-p"),
- VerboseFlag,
- SfoFlag,
- Language,
- DriverFlag
- );
+ ShellStatus = DoDhByProtocol (ProtocolVal, VerboseFlag, SfoFlag, Language, DriverFlag);
}
- } else {
- RawValue = ShellCommandLineGetRawValue(Package, 1);
- if (RawValue == NULL) {
+ } else if ((RawValue != NULL) &&
+ (gUnicodeCollation->StriColl(gUnicodeCollation, L"decode", (CHAR16 *) RawValue) == 0)) {
+ if (ShellCommandLineGetFlag (Package, L"-p") && (ProtocolVal == NULL)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-p");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
//
- // Print everything
+ // Print decode informatino by protocol.
//
- ShellStatus = DoDhForAll(
- SfoFlag,
- VerboseFlag,
- Language,
- DriverFlag
- );
+ ShellStatus = DoDecodeByProtocol (ProtocolVal, Language);
+ }
+ } else {
+ if (ShellCommandLineGetFlag (Package, L"-p")) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");
+ ShellStatus = SHELL_INVALID_PARAMETER;
} else {
- Status = ShellConvertStringToUint64(RawValue, &Intermediate, TRUE, FALSE);
- if (EFI_ERROR(Status) || ConvertHandleIndexToHandle((UINTN)Intermediate) == NULL) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", RawValue);
+ Status = ShellConvertStringToUint64 (RawValue, &Intermediate, TRUE, FALSE);
+ if (EFI_ERROR(Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", RawValue);
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
- //
- // print 1 handle
- //
- DoDhByHandle(
- ConvertHandleIndexToHandle((UINTN)Intermediate),
- VerboseFlag,
- SfoFlag,
- Language,
- DriverFlag,
- FALSE
- );
+ Handle = ConvertHandleIndexToHandle ((UINTN) Intermediate);
+ if (Handle == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", RawValue);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ //
+ // Print information by handle.
+ //
+ DoDhByHandle (Handle, VerboseFlag, SfoFlag, Language, DriverFlag, FALSE);
+ }
}
}
}
-
ShellCommandLineFreeVarList (Package);
SHELL_FREE_NON_NULL(Language);
}
diff --git a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.uni b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.uni
index ac520e2..52156d5 100644
--- a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.uni
+++ b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.uni
@@ -2,7 +2,7 @@
//
// (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
// (C) Copyright 2012-2015 Hewlett-Packard Development Company, L.P.<BR>
-// Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
// This program and the accompanying materials
// are licensed and made available under the terms and conditions of the BSD License
// which accompanies this distribution. The full text of the license may be found at
@@ -98,9 +98,14 @@
#string STR_DRIVERS_ITEM_LINE #language en-US "%H%3x%N %08x %1c %1c %1c %3d %3d %-35s %s\r\n"
#string STR_DRIVERS_ITEM_LINE_SFO #language en-US "DriversInfo,"%x","%x","%c","%c","%c","%d","%d","%s","%s"\r\n"
-#string STR_DH_NO_GUID_FOUND #language en-US "Protocol ID '%s' could not be identified.\r\n"
+#string STR_DH_OUTPUT_DECODE #language en-US "%s: %g\r\n"
+#string STR_DH_NO_NAME_FOUND #language en-US "Protocol Name '%s' could not be identified.\r\n"
+#string STR_DH_NO_GUID_FOUND #language en-US "Protocol GUID '%g' could not be identified.\r\n"
#string STR_DH_SFO_OUTPUT #language en-US "%s, %s, %H%02x%N, %s, &s\r\n"
#string STR_DH_OUTPUT #language en-US "%H%02x%N: %s\r\n"
+#string STR_DH_OUTPUT_ALL_HEADER #language en-US "Handle dump\r\n"
+#string STR_DH_OUTPUT_GUID_HEADER #language en-US "Handle dump by protocol '%g'\r\n"
+#string STR_DH_OUTPUT_NAME_HEADER #language en-US "Handle dump by protocol '%s'\r\n"
#string STR_DH_OUTPUT_SINGLE #language en-US "%H%02x%N: %x\r\n%s"
#string STR_DH_OUTPUT_SFO #language en-US "%s, %s, %s, %H%02x%N, %s, %s\r\n"
#string STR_DH_OUTPUT_DRIVER1 #language en-US " Controller Name : %B%s%N\r\n"
--
2.9.0.windows.1
next prev parent reply other threads:[~2017-01-09 9:31 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-09 9:30 [PATCH 0/5] Change "dh" to support dump from GUID and "decode" parameter Ruiyu Ni
2017-01-09 9:30 ` [PATCH 1/5] ShellPkg/HandleParsingLib: Rename global variables Ruiyu Ni
2017-01-09 9:30 ` [PATCH 2/5] ShellPkg/HandleParsingLib: Return NULL name for unknown GUID Ruiyu Ni
2017-01-09 9:30 ` [PATCH 3/5] ShellPkg/HandleParsingLib: Add new API GetAllMappingGuids Ruiyu Ni
2017-01-09 9:30 ` [PATCH 4/5] ShellPkg/Dh: Fix coding style issues Ruiyu Ni
2017-01-09 15:36 ` Carsey, Jaben
2017-01-10 2:24 ` Ni, Ruiyu
2017-01-10 16:20 ` Carsey, Jaben
2017-01-09 9:30 ` Ruiyu Ni [this message]
2017-01-09 15:40 ` [PATCH 0/5] Change "dh" to support dump from GUID and "decode" parameter Carsey, Jaben
2017-01-10 2:23 ` Ni, Ruiyu
2017-01-10 21:43 ` Carsey, Jaben
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170109093052.140504-6-ruiyu.ni@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox