From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by ml01.01.org (Postfix) with ESMTP id BE84F1A1DF3 for ; Mon, 8 Aug 2016 22:44:50 -0700 (PDT) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga102.jf.intel.com with ESMTP; 08 Aug 2016 22:44:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,493,1464678000"; d="scan'208";a="152809860" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by fmsmga004.fm.intel.com with ESMTP; 08 Aug 2016 22:44:50 -0700 Received: from shsmsx152.ccr.corp.intel.com (10.239.6.52) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.248.2; Mon, 8 Aug 2016 22:44:48 -0700 Received: from shsmsx103.ccr.corp.intel.com ([169.254.4.181]) by SHSMSX152.ccr.corp.intel.com ([169.254.6.107]) with mapi id 14.03.0248.002; Tue, 9 Aug 2016 13:44:32 +0800 From: "Ni, Ruiyu" To: "Ni, Ruiyu" , "edk2-devel@lists.01.org" CC: "Carsey, Jaben" Thread-Topic: [edk2] [PATCH v2 1/6] ShellPkg: TAB logic incorrectly chops out fs0: when typing fs0: Thread-Index: AQHR8gEDtTFX4GyjfUSqYJgBhELIq6BAHhFg Date: Tue, 9 Aug 2016 05:44:33 +0000 Message-ID: <734D49CCEBEEF84792F5B80ED585239D1ADB4A20@SHSMSX103.ccr.corp.intel.com> References: <20160809054338.170452-1-ruiyu.ni@intel.com> In-Reply-To: <20160809054338.170452-1-ruiyu.ni@intel.com> Accept-Language: en-US, zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 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 05:44:50 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable This v2 patch fixed VS2012 build failure. Thanks/Ray > -----Original Message----- > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of > Ruiyu Ni > Sent: Tuesday, August 9, 2016 1:44 PM > To: edk2-devel@lists.01.org > Cc: Carsey, Jaben > Subject: [edk2] [PATCH v2 1/6] ShellPkg: TAB logic incorrectly chops out = fs0: > when typing fs0: >=20 > 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(-) >=20 > diff --git a/ShellPkg/Application/Shell/FileHandleWrappers.c > b/ShellPkg/Application/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, > + 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= directory. > + // > + 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) / sizeof (CHAR16) - 1 - StrLen (TabStr)); > + Status =3D ShellInfoObject.NewEfiShellProtocol->FindFiles(TabStr, > + &FileList); > + > + // > + // 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- > >Link); !IsNull (&FileList->Link, &FileInfo->Link); ) { > + if (((StrCmp (FileInfo->FileName, L".") =3D=3D 0) || (StrCmp (File= Info- > >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-= >Link); > + InternalFreeShellFileInfoNode (TempFileInfo); > + } else { > + FileInfo =3D (EFI_SHELL_FILE_INFO *) GetNextNode (&FileList->Lin= k, > &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 updat= ed by TAB > stroke > UINTN Column; // Column of current cursor > UINTN Row; // Row of current cursor > UINTN StartColumn; // Column at the beginning of the = line > @@ -334,7 +463,6 @@ FileInterfaceStdInRead( > UINTN StringLen; // Total length of the line > UINTN StringCurPos; // Line index corresponding to the= cursor > 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 se= arch for TAB > completion. > - UINTN TabUpdatePos; // Start index of the string updat= ed 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 buff= er > 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 (&FoundFileL= ist); > - DEBUG_CODE(FoundFileList =3D NULL;); > - } > - InTabScrolling =3D FALSE; > + if (TabCompleteList !=3D NULL) { > + ShellInfoObject.NewEfiShellProtocol->FreeFileList (&TabCompleteL= ist); > + 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(&(FoundFileLi= st- > >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, *B= ufferSize, > &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, > (*BufferSize)/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, > - (*BufferSize)/sizeof(CHAR16), > - CurrentString + TabPos, > - 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 > + (&TabCompleteList->Link); > } else { > - StrnCpyS(TabStr, (*BufferSize)/sizeof(CHAR16), CurrentString += TabPos, > (*BufferSize)/sizeof(CHAR16) - 1); > + TabCurrent =3D (EFI_SHELL_FILE_INFO*) GetNextNode > + (&TabCompleteList->Link, &TabCurrent->Link); > } > - StrnCatS(TabStr, (*BufferSize)/sizeof(CHAR16), L"*", > (*BufferSize)/sizeof(CHAR16) - 1 - StrLen(TabStr)); > - FoundFileList =3D NULL; > - Status =3D ShellInfoObject.NewEfiShellProtocol->FindFiles(TabSt= r, > &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(&(FoundFileList->Link)) > - ; !IsNull(&FoundFileList->Link, &TempPos->Link) > - ; TempPos =3D (EFI_SHELL_FILE_INFO*)GetNextNode(&(FoundFil= eList- > >Link), &(TempPos->Link)) > - ){ > - // > - // If "cd" is typed, only directory name will be auto-comple= te 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_SUCCE= SS) > - ||(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(&(Tem= pPos- > >Link))->BackLink); > - InternalFreeShellFileInfoNode(TabLinePos); > - } > - } > - if (FoundFileList !=3D NULL && !IsListEmpty(&FoundFileList->Li= nk)) { > - TabLinePos =3D (EFI_SHELL_FILE_INFO*)GetFirstNode(&FoundFile= List- > >Link); > - InTabScrolling =3D TRUE; > - } else { > - ShellInfoObject.NewEfiShellProtocol->FreeFileList (&FoundFil= eList); > - } > + if (IsNull(&TabCompleteList->Link, &TabCurrent->Link)) { > + TabCurrent =3D (EFI_SHELL_FILE_INFO*) GetNextNode > + (&TabCompleteList->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 * > sizeof (CHAR16)); > + CopyMem (TabOutputStr + 1, TabCurrent->FileName, OutputLength * > + sizeof (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 > (TabOutputStr) : 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; > } > -- > 2.9.0.windows.1 >=20 > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel