From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM01-BN3-obe.outbound.protection.outlook.com (mail-bn3nam01on0718.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe41::718]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 429081A1E18 for ; Tue, 9 Aug 2016 08:08:22 -0700 (PDT) Received: from CS1PR84MB0229.NAMPRD84.PROD.OUTLOOK.COM (10.162.190.151) by CS1PR84MB0232.NAMPRD84.PROD.OUTLOOK.COM (10.162.190.154) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.549.15; Tue, 9 Aug 2016 15:08:19 +0000 Received: from CS1PR84MB0229.NAMPRD84.PROD.OUTLOOK.COM ([10.162.190.151]) by CS1PR84MB0229.NAMPRD84.PROD.OUTLOOK.COM ([10.162.190.151]) with mapi id 15.01.0549.025; Tue, 9 Aug 2016 15:08:19 +0000 From: "Shah, Tapan" To: Ruiyu Ni , "edk2-devel@lists.01.org" CC: Jaben Carsey Thread-Topic: [edk2] [PATCH v2 1/6] ShellPkg: TAB logic incorrectly chops out fs0: when typing fs0: Thread-Index: AQHR8gEJ5mRPTEmaCkOccHO17ipmMKBAu5Qg Date: Tue, 9 Aug 2016 15:08:18 +0000 Message-ID: References: <20160809054338.170452-1-ruiyu.ni@intel.com> In-Reply-To: <20160809054338.170452-1-ruiyu.ni@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=tapandshah@hpe.com; x-originating-ip: [15.203.227.10] x-ms-office365-filtering-correlation-id: 132edd0e-b175-4c70-6e8c-08d3c066ff34 x-microsoft-exchange-diagnostics: 1; CS1PR84MB0232; 6:I0RudQYSNTtMebADc18yl9whp6rgGaRcJWQ3KsA8pEnCEDQyWR2gxYPPL6ff6Zaf9sDWS70uCDEfNPK2pkxpJVdBDCIZqwhLE/V56RU7V4AUxynxKK0YwumsM0WmHdzz3yVt1UPRScCnXzedNycwjsS25tYZzysrRbXc2XYtRnei9wIiYZW+ZVa4VD4wJZD3pdFp7qSUkjw6P1PV/mcQLFjYvOWGS4mD0m/YQ44wBGzVo/gHd19RMSt+4EOvIiqz7BN8H7b/bbO70dSNwWfz45Qyi0J5y3tSlFwwrT+0L0cIqhjlaOrqfhRMBHz8LGwD/bD0g+4OcyH2RKPF2ouEGw==; 5:GAvfvVvPbcMRNkJddETi3NTOoklAYJVECTwBrhI/4EeWC282NAhxAIw1EkeseaKzz70rjTAQ8csbDrD7YYz/lBtLh6qF6v427RFcXCR+5His2d+sY5zLEftHFdmQVjC9EvLI9PJrAWvLXPJ56tk0CQ==; 24:MiWsMv36nFsbvVdsiMF69VzSiaMmCCLHsh2ewzjLotmXGHRQ8T+lJzhUpmmNcarg0fJDBf6Ok6c4+mpoI5HrNyOBf1CoL2TCnPNDWKtybXU=; 7:l08D0/MDon7Y0wB/6fHDvztkjZGbE9iEeUoxsehY2HqfQgrSIH2xR92zsx7ClgnspT1m6w4EhtwgNPK2oj6s90fngo7njFW5UhcuVpuXFKrcYtbK/d4gC17X/r80C/cigLqjdSdTZ10Gsvf/9kJadjI8q0B2ct7c9VQtPGzEnqWeKTrJ79eWGSWK0ddrZtQGi/c2yuiVpBSgfHBNvOgzHXfzj2x6FbqsKzMkBtiDeRQYe9iY1tVV3elYV3tsR5om x-microsoft-antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CS1PR84MB0232; x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(227479698468861)(162533806227266)(228905959029699); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6055026); SRVR:CS1PR84MB0232; BCL:0; PCL:0; RULEID:; SRVR:CS1PR84MB0232; x-forefront-prvs: 0029F17A3F x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(6009001)(7916002)(377454003)(13464003)(199003)(189002)(81166006)(81156014)(68736007)(7736002)(7846002)(7696003)(87936001)(305945005)(105586002)(74316002)(8676002)(101416001)(86362001)(99286002)(5001770100001)(3660700001)(97736004)(3280700002)(189998001)(50986999)(33656002)(54356999)(76176999)(106116001)(106356001)(10400500002)(9686002)(8936002)(15975445007)(2950100001)(2900100001)(77096005)(66066001)(19580405001)(19580395003)(5002640100001)(2906002)(586003)(4326007)(92566002)(6116002)(2501003)(102836003)(122556002)(3846002)(11100500001)(403724002); DIR:OUT; SFP:1102; SCL:1; SRVR:CS1PR84MB0232; H:CS1PR84MB0229.NAMPRD84.PROD.OUTLOOK.COM; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; received-spf: None (protection.outlook.com: hpe.com does not designate permitted sender hosts) spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: hpe.com X-MS-Exchange-CrossTenant-originalarrivaltime: 09 Aug 2016 15:08:18.8453 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 105b2061-b669-4b31-92ac-24d304d195dc X-MS-Exchange-Transport-CrossTenantHeadersStamped: CS1PR84MB0232 Subject: Re: [PATCH v2 1/6] ShellPkg: TAB logic incorrectly chops out fs0: when typing fs0: X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Aug 2016 15:08:22 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Series Reviewed By: Tapan Shah -----Original Message----- From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Ruiy= u Ni Sent: Tuesday, August 09, 2016 12:44 AM To: edk2-devel@lists.01.org Cc: Jaben Carsey Subject: [edk2] [PATCH v2 1/6] ShellPkg: TAB logic incorrectly chops out fs= 0: when typing fs0: Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Cc: Jaben Carsey --- ShellPkg/Application/Shell/FileHandleWrappers.c | 312 ++++++++++++++------= ---- 1 file changed, 185 insertions(+), 127 deletions(-) diff --git a/ShellPkg/Application/Shell/FileHandleWrappers.c b/ShellPkg/App= lication/Shell/FileHandleWrappers.c index f6a82ee..0091934 100644 --- a/ShellPkg/Application/Shell/FileHandleWrappers.c +++ b/ShellPkg/Application/Shell/FileHandleWrappers.c @@ -293,6 +293,134 @@ FileInterfaceNulWrite( } =20 /** + Create the TAB completion list. + + @param[in] InputString The command line to expand. + @param[in] StringLen Length of the command line. + @param[in] BufferSize Buffer size. + @param[out] TabCompletionList Return the TAB completion list. + @param[out] TabUpdatePos Return the TAB update position. +**/ +EFI_STATUS +EFIAPI +CreateTabCompletionList ( + IN CONST CHAR16 *InputString, + IN CONST UINTN StringLen,=20 + IN CONST UINTN BufferSize, + IN OUT EFI_SHELL_FILE_INFO **TabCompletionList, + IN OUT UINTN *TabUpdatePos +) +{ + BOOLEAN InQuotation; + UINTN TabPos; + UINTN Index; + CONST CHAR16 *Cwd; + EFI_STATUS Status; + CHAR16 *TabStr; + EFI_SHELL_FILE_INFO *FileList; + EFI_SHELL_FILE_INFO *FileInfo; + EFI_SHELL_FILE_INFO *TempFileInfo; + + // + // Allocate buffers + // + TabStr =3D AllocateZeroPool (BufferSize); + if (TabStr =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // handle auto complete of file and directory names... + // E.g.: cd fs0:\EFI\Bo + // ^ ^ + // TabPos TabUpdatePos + // + TabPos =3D 0; + *TabUpdatePos =3D 0; + FileList =3D NULL; + InQuotation =3D FALSE; + for (Index =3D 0; Index < StringLen; Index++) { + switch (InputString[Index]) { + case L'\"': + InQuotation =3D (BOOLEAN) (!InQuotation); + break; + + case L' ': + if (!InQuotation) { + TabPos =3D Index + 1; + *TabUpdatePos =3D TabPos; + } + break; + + case L':': + // + // handle the case "fs0:" + // Update the TabUpdatePos as well. + // + case L'\\': + *TabUpdatePos =3D Index + 1; + break; + + default: + break; + } + } + + if (StrStr (InputString + TabPos, L":") =3D=3D NULL) { + // + // If file path doesn't contain ":", it's a path relative to current d= irectory. + // + Cwd =3D ShellInfoObject.NewEfiShellProtocol->GetCurDir (NULL); + if (Cwd !=3D NULL) { + StrnCpyS (TabStr, (BufferSize) / sizeof (CHAR16), Cwd, (BufferSize) = / sizeof (CHAR16) - 1); + if (InputString[TabPos] !=3D L'\\') { + StrCatS (TabStr, (BufferSize) / sizeof (CHAR16), L"\\"); + } + } + } + StrnCatS (TabStr, (BufferSize) / sizeof (CHAR16), InputString + TabPos, = StringLen - TabPos); + StrnCatS (TabStr, (BufferSize) / sizeof (CHAR16), L"*", (BufferSize) / s= izeof (CHAR16) - 1 - StrLen (TabStr)); + Status =3D ShellInfoObject.NewEfiShellProtocol->FindFiles(TabStr, &File= List); + + // + // Filter out the non-directory for "CD" command + // Filter "." and ".." for all + // + if (!EFI_ERROR (Status) && FileList !=3D NULL) { + // + // Skip the spaces in the beginning + // + while (*InputString =3D=3D L' ') { + InputString++; + } + + for (FileInfo =3D (EFI_SHELL_FILE_INFO *) GetFirstNode (&FileList->Lin= k); !IsNull (&FileList->Link, &FileInfo->Link); ) { + if (((StrCmp (FileInfo->FileName, L".") =3D=3D 0) || (StrCmp (FileIn= fo->FileName, L"..") =3D=3D 0)) || + (((InputString[0] =3D=3D L'c' || InputString[0] =3D=3D L'C') && = (InputString[1] =3D=3D L'd' || InputString[1] =3D=3D L'D')) && + (ShellIsDirectory (FileInfo->FullName) !=3D EFI_SUCCESS))) { + TempFileInfo =3D FileInfo; + FileInfo =3D (EFI_SHELL_FILE_INFO *) RemoveEntryList (&FileInfo->L= ink); + InternalFreeShellFileInfoNode (TempFileInfo); + } else { + FileInfo =3D (EFI_SHELL_FILE_INFO *) GetNextNode (&FileList->Link,= &FileInfo->Link); + } + } + } + + if (FileList !=3D NULL && !IsListEmpty (&FileList->Link)) { + Status =3D EFI_SUCCESS; + } else { + ShellInfoObject.NewEfiShellProtocol->FreeFileList (&FileList); + Status =3D EFI_NOT_FOUND; + } + + FreePool (TabStr); + + *TabCompletionList =3D FileList; + return Status; +} + +/** File style interface for console (Read). =20 This will return a single line of input from the console. @@ -326,6 +454,7 @@ FileInterfaceStdInRead( { CHAR16 *CurrentString; BOOLEAN Done; + UINTN TabUpdatePos; // Start index of the string updated= by TAB stroke UINTN Column; // Column of current cursor UINTN Row; // Row of current cursor UINTN StartColumn; // Column at the beginning of the li= ne @@ -334,7 +463,6 @@ FileInterfaceStdInRead( UINTN StringLen; // Total length of the line UINTN StringCurPos; // Line index corresponding to the c= ursor UINTN MaxStr; // Maximum possible line length - UINTN Index; UINTN TotalColumn; // Num of columns in the console UINTN TotalRow; // Num of rows in the console UINTN SkipLength; @@ -348,18 +476,10 @@ FileInterfaceStdInRead( BOOLEAN InScrolling; EFI_STATUS Status; BOOLEAN InTabScrolling; // Whether in TAB-completion state - EFI_SHELL_FILE_INFO *FoundFileList; - EFI_SHELL_FILE_INFO *TabLinePos; - EFI_SHELL_FILE_INFO *TempPos; - CHAR16 *TabStr; - CHAR16 *TabOutputStr; - BOOLEAN InQuotationMode; - CHAR16 *TempStr; - UINTN TabPos; // Start index of the string to sear= ch for TAB completion. - UINTN TabUpdatePos; // Start index of the string updated= by TAB stroke -// UINTN Count; + EFI_SHELL_FILE_INFO *TabCompleteList; + EFI_SHELL_FILE_INFO *TabCurrent; UINTN EventIndex; - CONST CHAR16 *Cwd; + CHAR16 *TabOutputStr; =20 // // If buffer is not large enough to hold a CHAR16, return minimum buffer= size @@ -380,24 +500,10 @@ FileInterfaceStdInRead( InScrolling =3D FALSE; InTabScrolling =3D FALSE; Status =3D EFI_SUCCESS; - TabLinePos =3D NULL; - FoundFileList =3D NULL; - TempPos =3D NULL; - TabPos =3D 0; + TabOutputStr =3D NULL; TabUpdatePos =3D 0; - - // - // Allocate buffers - // - TabStr =3D AllocateZeroPool (*BufferSize); - if (TabStr =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - TabOutputStr =3D AllocateZeroPool (*BufferSize); - if (TabOutputStr =3D=3D NULL) { - FreePool(TabStr); - return EFI_OUT_OF_RESOURCES; - } + TabCompleteList =3D NULL; + TabCurrent =3D NULL; =20 // // Get the screen setting and the current cursor location @@ -454,11 +560,11 @@ FileInterfaceStdInRead( // If we are quitting TAB scrolling... // if (InTabScrolling && Key.UnicodeChar !=3D CHAR_TAB) { - if (FoundFileList !=3D NULL) { - ShellInfoObject.NewEfiShellProtocol->FreeFileList (&FoundFileLis= t); - DEBUG_CODE(FoundFileList =3D NULL;); - } - InTabScrolling =3D FALSE; + if (TabCompleteList !=3D NULL) { + ShellInfoObject.NewEfiShellProtocol->FreeFileList (&TabCompleteLis= t); + DEBUG_CODE(TabCompleteList =3D NULL;); + } + InTabScrolling =3D FALSE; } =20 switch (Key.UnicodeChar) { @@ -491,95 +597,39 @@ FileInterfaceStdInRead( break; =20 case CHAR_TAB: - // - // handle auto complete of file and directory names... - // - if (InTabScrolling) { - ASSERT(FoundFileList !=3D NULL); - ASSERT(TabLinePos !=3D NULL); - TabLinePos =3D (EFI_SHELL_FILE_INFO*)GetNextNode(&(FoundFileList->= Link), &TabLinePos->Link); - if (IsNull(&(FoundFileList->Link), &TabLinePos->Link)) { - TabLinePos =3D (EFI_SHELL_FILE_INFO*)GetNextNode(&(FoundFileList= ->Link), &TabLinePos->Link); - } - } else { - TabPos =3D 0; - TabUpdatePos =3D 0; - InQuotationMode =3D FALSE; - for (Index =3D 0; Index < StringLen; Index++) { - if (CurrentString[Index] =3D=3D L'\"') { - InQuotationMode =3D (BOOLEAN)(!InQuotationMode); - } - if (CurrentString[Index] =3D=3D L' ' && !InQuotationMode) { - TabPos =3D Index + 1; - TabUpdatePos =3D Index + 1; - } - if (CurrentString[Index] =3D=3D L'\\') { - TabUpdatePos =3D Index + 1; - } + if (!InTabScrolling) { + TabCurrent =3D NULL; + // + // Initialize a tab complete operation. + // + Status =3D CreateTabCompletionList (CurrentString, StringLen, *Buf= ferSize, &TabCompleteList, &TabUpdatePos); + if (!EFI_ERROR(Status)) { + InTabScrolling =3D TRUE; } - if (StrStr(CurrentString + TabPos, L":") =3D=3D NULL) { - Cwd =3D ShellInfoObject.NewEfiShellProtocol->GetCurDir(NULL); - if (Cwd !=3D NULL) { - StrnCpyS(TabStr, (*BufferSize)/sizeof(CHAR16), Cwd, (*BufferSi= ze)/sizeof(CHAR16) - 1); - StrCatS(TabStr, (*BufferSize)/sizeof(CHAR16), L"\\"); - if (TabStr[StrLen(TabStr)-1] =3D=3D L'\\' && *(CurrentString += TabPos) =3D=3D L'\\' ) { - TabStr[StrLen(TabStr)-1] =3D CHAR_NULL; - } - StrnCatS( TabStr,=20 - (*BufferSize)/sizeof(CHAR16),=20 - CurrentString + TabPos,=20 - StringLen - TabPos - ); - } else { - *TabStr =3D CHAR_NULL; - StrnCatS(TabStr, (*BufferSize)/sizeof(CHAR16), CurrentString += TabPos, StringLen - TabPos); - } + + // + // We do not set up the replacement. + // The next section will do that. + // + } + + if (InTabScrolling) { + // + // We are in a tab complete operation. + // set up the next replacement. + // + ASSERT(TabCompleteList !=3D NULL); + if (TabCurrent =3D=3D NULL) { + TabCurrent =3D (EFI_SHELL_FILE_INFO*) GetFirstNode (&TabComplete= List->Link); } else { - StrnCpyS(TabStr, (*BufferSize)/sizeof(CHAR16), CurrentString + T= abPos, (*BufferSize)/sizeof(CHAR16) - 1); + TabCurrent =3D (EFI_SHELL_FILE_INFO*) GetNextNode (&TabCompleteL= ist->Link, &TabCurrent->Link); } - StrnCatS(TabStr, (*BufferSize)/sizeof(CHAR16), L"*", (*BufferSize)= /sizeof(CHAR16) - 1 - StrLen(TabStr)); - FoundFileList =3D NULL; - Status =3D ShellInfoObject.NewEfiShellProtocol->FindFiles(TabStr,= &FoundFileList); - for ( TempStr =3D CurrentString - ; *TempStr =3D=3D L' ' - ; TempStr++); // note the ';'... empty for loop + // - // make sure we have a list before we do anything more... + // Skip over the empty list beginning node // - if (EFI_ERROR (Status) || FoundFileList =3D=3D NULL) { - InTabScrolling =3D FALSE; - TabLinePos =3D NULL; - continue; - } else { - // - // enumerate through the list of files - // - for ( TempPos =3D (EFI_SHELL_FILE_INFO*)GetFirstNode(&(FoundFile= List->Link)) - ; !IsNull(&FoundFileList->Link, &TempPos->Link) - ; TempPos =3D (EFI_SHELL_FILE_INFO*)GetNextNode(&(FoundFileL= ist->Link), &(TempPos->Link)) - ){ - // - // If "cd" is typed, only directory name will be auto-complete= filled - // in either case . and .. will be removed. - // - if ((((TempStr[0] =3D=3D L'c' || TempStr[0] =3D=3D L'C') && - (TempStr[1] =3D=3D L'd' || TempStr[1] =3D=3D L'D') - ) && ((ShellIsDirectory(TempPos->FullName) !=3D EFI_SUCCESS= ) - ||(StrCmp(TempPos->FileName, L".") =3D=3D 0) - ||(StrCmp(TempPos->FileName, L"..") =3D=3D 0) - )) || ((StrCmp(TempPos->FileName, L".") =3D=3D 0) - ||(StrCmp(TempPos->FileName, L"..") =3D=3D 0))){ - TabLinePos =3D TempPos; - TempPos =3D (EFI_SHELL_FILE_INFO*)(RemoveEntryList(&(TempP= os->Link))->BackLink); - InternalFreeShellFileInfoNode(TabLinePos); - } - } - if (FoundFileList !=3D NULL && !IsListEmpty(&FoundFileList->Link= )) { - TabLinePos =3D (EFI_SHELL_FILE_INFO*)GetFirstNode(&FoundFileLi= st->Link); - InTabScrolling =3D TRUE; - } else { - ShellInfoObject.NewEfiShellProtocol->FreeFileList (&FoundFileL= ist); - } + if (IsNull(&TabCompleteList->Link, &TabCurrent->Link)) { + TabCurrent =3D (EFI_SHELL_FILE_INFO*) GetNextNode (&TabCompleteL= ist->Link, &TabCurrent->Link); } } break; @@ -720,23 +770,31 @@ FileInterfaceStdInRead( // the next file or directory name // if (InTabScrolling) { + TabOutputStr =3D AllocateZeroPool (*BufferSize); + if (TabOutputStr =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + } + } + + if (InTabScrolling && TabOutputStr !=3D NULL) { + // // Adjust the column and row to the start of TAB-completion string. // Column =3D (StartColumn + TabUpdatePos) % TotalColumn; Row -=3D (StartColumn + StringCurPos) / TotalColumn - (StartColumn += TabUpdatePos) / TotalColumn; - OutputLength =3D StrLen (TabLinePos->FileName); + OutputLength =3D StrLen (TabCurrent->FileName); // // if the output string contains blank space, quotation marks L'\"' // should be added to the output. // - if (StrStr(TabLinePos->FileName, L" ") !=3D NULL){ + if (StrStr(TabCurrent->FileName, L" ") !=3D NULL){ TabOutputStr[0] =3D L'\"'; - CopyMem (TabOutputStr + 1, TabLinePos->FileName, OutputLength * si= zeof (CHAR16)); + CopyMem (TabOutputStr + 1, TabCurrent->FileName, OutputLength * si= zeof (CHAR16)); TabOutputStr[OutputLength + 1] =3D L'\"'; TabOutputStr[OutputLength + 2] =3D CHAR_NULL; } else { - CopyMem (TabOutputStr, TabLinePos->FileName, OutputLength * sizeof= (CHAR16)); + CopyMem (TabOutputStr, TabCurrent->FileName, OutputLength * sizeof= (CHAR16)); TabOutputStr[OutputLength] =3D CHAR_NULL; } OutputLength =3D StrLen (TabOutputStr) < MaxStr - 1 ? StrLen (TabOut= putStr) : MaxStr - 1; @@ -747,6 +805,8 @@ FileInterfaceStdInRead( if (StringLen > TabUpdatePos + OutputLength) { Delete =3D StringLen - TabUpdatePos - OutputLength; } + + FreePool(TabOutputStr); } =20 // @@ -850,8 +910,6 @@ FileInterfaceStdInRead( AddLineToCommandHistory(CurrentString); } =20 - FreePool (TabStr); - FreePool (TabOutputStr); // // Return the data to the caller // @@ -861,10 +919,10 @@ FileInterfaceStdInRead( // if this was used it should be deallocated by now... // prevent memory leaks... // - if (FoundFileList !=3D NULL) { - ShellInfoObject.NewEfiShellProtocol->FreeFileList (&FoundFileList); + if (TabCompleteList !=3D NULL) { + ShellInfoObject.NewEfiShellProtocol->FreeFileList (&TabCompleteList); } - ASSERT(FoundFileList =3D=3D NULL); + ASSERT(TabCompleteList =3D=3D NULL); =20 return Status; } --=20 2.9.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel