Exemplo n.º 1
0
Arquivo: Mv.c Projeto: alt0174/edk2
/**
  function to determine if a move is between file systems.
  
  @param FullName [in]    The name of the file to move.
  @param Cwd      [in]    The current working directory
  @param DestPath [in]    The target location to move to

  @retval TRUE            The move is across file system.
  @retval FALSE           The move is within a file system.
**/
BOOLEAN
EFIAPI
IsBetweenFileSystem(
  IN CONST CHAR16     *FullName,
  IN CONST CHAR16     *Cwd,
  IN CONST CHAR16     *DestPath
  )
{
  CHAR16  *Test;
  CHAR16  *Test1;
  UINTN   Result;

  Test = StrStr(FullName, L":");
  if (Test == NULL && Cwd != NULL) {
    Test = StrStr(Cwd, L":");
  }
  Test1 = StrStr(DestPath, L":");
  if (Test1 == NULL && Cwd != NULL) {
    Test1 = StrStr(Cwd, L":");
  }
  if (Test1 != NULL && Test != NULL) {
    *Test = CHAR_NULL;
    *Test1 = CHAR_NULL;
    Result = StringNoCaseCompare(&FullName, &DestPath);
    *Test = L':';
    *Test1 = L':';
    if (Result != 0) {
      return (TRUE);
    }
  }
  return (FALSE);
}
Exemplo n.º 2
0
Arquivo: Mv.c Projeto: alt0174/edk2
/**
  Function to validate that moving a specific file (FileName) to a specific
  location (DestPath) is valid.

  This function will verify that the destination is not a subdirectory of
  FullName, that the Current working Directory is not being moved, and that
  the directory is not read only.

  if the move is invalid this function will report the error to StdOut.

  @param SourcePath [in]    The name of the file to move.
  @param Cwd        [in]    The current working directory
  @param DestPath   [in]    The target location to move to
  @param Attribute  [in]    The Attribute of the file
  @param DestAttr   [in]    The Attribute of the destination
  @param FileStatus [in]    The Status of the file when opened

  @retval TRUE        The move is valid
  @retval FALSE       The move is not
**/
BOOLEAN
EFIAPI
IsValidMove(
  IN CONST CHAR16     *SourcePath,
  IN CONST CHAR16     *Cwd,
  IN CONST CHAR16     *DestPath,
  IN CONST UINT64     Attribute,
  IN CONST UINT64     DestAttr,
  IN CONST EFI_STATUS FileStatus
  )
{
  CHAR16  *DestPathCopy;
  CHAR16  *DestPathWalker;

  if (Cwd != NULL && StrCmp(SourcePath, Cwd) == 0) {
    //
    // Invalid move
    //
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MV_INV_CWD), gShellLevel2HiiHandle);
    return (FALSE);
  }

  //
  // invalid to move read only or move to a read only destination
  //
  if (((Attribute & EFI_FILE_READ_ONLY) != 0) 
    || (FileStatus == EFI_WRITE_PROTECTED)
    || ((DestAttr & EFI_FILE_READ_ONLY) != 0)
    ) {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MV_INV_RO), gShellLevel2HiiHandle, SourcePath);
    return (FALSE);
  }  
  
  DestPathCopy = AllocateCopyPool(StrSize(DestPath), DestPath);
  if (DestPathCopy == NULL) {
    return (FALSE);
  }

  for (DestPathWalker = DestPathCopy; *DestPathWalker == L'\\'; DestPathWalker++) ;

  while(DestPathWalker != NULL && DestPathWalker[StrLen(DestPathWalker)-1] == L'\\') {
    DestPathWalker[StrLen(DestPathWalker)-1] = CHAR_NULL;
  }

  ASSERT(DestPathWalker != NULL);
  ASSERT(SourcePath   != NULL);

  //
  // If they're the same, or if source is "above" dest on file path tree
  //
  if ( StringNoCaseCompare (&DestPathWalker, &SourcePath) == 0 ||
       ((StrStr(DestPathWalker, SourcePath) == DestPathWalker) && 
        (DestPathWalker[StrLen(SourcePath)] == '\\')
       )
     ) {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MV_INV_SUB), gShellLevel2HiiHandle);
    FreePool(DestPathCopy);
    return (FALSE);
  }
  FreePool(DestPathCopy);

  return (TRUE);
}
Exemplo n.º 3
0
/**
  Save lines in HBufferImage to disk.

  @param[in] FileName     The file name.

  @retval EFI_SUCCESS           The operation was successful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
  @retval EFI_LOAD_ERROR        A load error occured.
**/
EFI_STATUS
HFileImageSave (
  IN CHAR16 *FileName
  )
{

  LIST_ENTRY                      *Link;
  HEFI_EDITOR_LINE                *Line;
  CHAR16                          *Str;
  EFI_STATUS                      Status;
  UINTN                           NumLines;
  SHELL_FILE_HANDLE                 FileHandle;
  UINTN                           TotalSize;
  UINT8                           *Buffer;
  UINT8                           *Ptr;
  EDIT_FILE_TYPE                  BufferTypeBackup;

  BufferTypeBackup        = HBufferImage.BufferType;
  HBufferImage.BufferType = FileTypeFileBuffer;

  //
  // if is the old file
  //
  if (HFileImage.FileName != NULL && FileName != NULL && StrCmp (FileName, HFileImage.FileName) == 0) {
    //
    // check whether file exists on disk
    //
    if (ShellIsFile(FileName) == EFI_SUCCESS) {
      //
      // current file exists on disk
      // so if not modified, then not save
      //
      if (HBufferImage.Modified == FALSE) {
        return EFI_SUCCESS;
      }
      //
      // if file is read-only, set error
      //
      if (HFileImage.ReadOnly == TRUE) {
        StatusBarSetStatusString (L"Read Only File Can Not Be Saved");
        return EFI_SUCCESS;
      }
    }
  }

   if (ShellIsDirectory(FileName) == EFI_SUCCESS) {
    StatusBarSetStatusString (L"Directory Can Not Be Saved");
    return EFI_LOAD_ERROR;
  }

  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);

  if (!EFI_ERROR (Status)) {
    //
    // the file exits, delete it
    //
    Status = ShellDeleteFile (&FileHandle);
    if (EFI_ERROR (Status) || Status == EFI_WARN_DELETE_FAILURE) {
      StatusBarSetStatusString (L"Write File Failed");
      return EFI_LOAD_ERROR;
    }
 }

  //
  // write all the lines back to disk
  //
  NumLines  = 0;
  TotalSize = 0;
  for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {
    Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);

    if (Line->Size != 0) {
      TotalSize += Line->Size;
    }
    //
    // end of if Line -> Size != 0
    //
    NumLines++;
  }
  //
  // end of for Link
  //
  Buffer = AllocateZeroPool (TotalSize);
  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Ptr = Buffer;
  for (Link = HBufferImage.ListHead->ForwardLink; Link != HBufferImage.ListHead; Link = Link->ForwardLink) {
    Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);

    if (Line->Size != 0) {
      CopyMem (Ptr, Line->Buffer, Line->Size);
      Ptr += Line->Size;
    }
    //
    // end of if Line -> Size != 0
    //
  }


  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);

  if (EFI_ERROR (Status)) {
    StatusBarSetStatusString (L"Create File Failed");
    return EFI_LOAD_ERROR;
  }

  Status = ShellWriteFile (FileHandle, &TotalSize, Buffer);
  FreePool (Buffer);
  if (EFI_ERROR (Status)) {
    ShellDeleteFile (&FileHandle);
    return EFI_LOAD_ERROR;
  }

  ShellCloseFile(&FileHandle);

  HBufferImage.Modified = FALSE;

  //
  // set status string
  //
  Str = CatSPrint(NULL, L"%d Lines Wrote", NumLines);
  StatusBarSetStatusString (Str);
  FreePool (Str);

  //
  // now everything is ready , you can set the new file name to filebuffer
  //
  if ((BufferTypeBackup != FileTypeFileBuffer && FileName != NULL) ||
     (FileName != NULL && HFileImage.FileName != NULL && StringNoCaseCompare (&FileName, &HFileImage.FileName) != 0)){
    //
    // not the same
    //
    HFileImageSetFileName (FileName);
    if (HFileImage.FileName == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  HFileImage.ReadOnly = FALSE;

  return EFI_SUCCESS;
}
Exemplo n.º 4
0
Arquivo: Cp.c Projeto: Cutty/edk2
/**
  function to take a list of files to copy and a destination location and do
  the verification and copying of those files to that location.  This function
  will report any errors to the user and halt.

  The key is to have this function called ONLY once.  this allows for the parameter
  verification to happen correctly.

  @param[in] FileList           A LIST_ENTRY* based list of files to move.
  @param[in] DestDir            The destination location.
  @param[in] SilentMode         TRUE to eliminate screen output.
  @param[in] RecursiveMode      TRUE to copy directories.
  @param[in] Resp               The response to the overwrite query (if always).

  @retval SHELL_SUCCESS             the files were all moved.
  @retval SHELL_INVALID_PARAMETER   a parameter was invalid
  @retval SHELL_SECURITY_VIOLATION  a security violation ocurred
  @retval SHELL_WRITE_PROTECTED     the destination was write protected
  @retval SHELL_OUT_OF_RESOURCES    a memory allocation failed
**/
SHELL_STATUS
EFIAPI
ValidateAndCopyFiles(
  IN CONST EFI_SHELL_FILE_INFO  *FileList,
  IN CONST CHAR16               *DestDir,
  IN BOOLEAN                    SilentMode,
  IN BOOLEAN                    RecursiveMode,
  IN VOID                       **Resp
  )
{
  CHAR16                    *HiiOutput;
  CHAR16                    *HiiResultOk;
  CONST EFI_SHELL_FILE_INFO *Node;
  SHELL_STATUS              ShellStatus;
  CHAR16                    *DestPath;
  VOID                      *Response;
  UINTN                     PathLen;
  CONST CHAR16              *Cwd;
  CONST CHAR16              *TempLocation;
  UINTN                     NewSize;

  if (Resp == NULL) {
    Response = NULL;
  } else {
    Response = *Resp;
  }

  DestPath    = NULL;
  ShellStatus = SHELL_SUCCESS;
  PathLen     = 0;
  Cwd         = ShellGetCurrentDir(NULL);

  ASSERT(FileList != NULL);
  ASSERT(DestDir  != NULL);

  //
  // We already verified that this was present.
  //
  ASSERT(Cwd      != NULL);

  //
  // If we are trying to copy multiple files... make sure we got a directory for the target...
  //
  if (EFI_ERROR(ShellIsDirectory(DestDir)) && FileList->Link.ForwardLink != FileList->Link.BackLink) {
    //
    // Error for destination not a directory
    //
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, DestDir);
    return (SHELL_INVALID_PARAMETER);
  }
  for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link)
    ;  !IsNull(&FileList->Link, &Node->Link)
    ;  Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link)
    ){
    //
    // skip the directory traversing stuff...
    //
    if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) {
      continue;
    }

    NewSize =  StrSize(DestDir);
    NewSize += StrSize(Node->FullName);
    NewSize += StrSize(Cwd);
    if (NewSize > PathLen) {
      PathLen = NewSize;
    }

    //
    // Make sure got -r if required
    //
    if (!RecursiveMode && !EFI_ERROR(ShellIsDirectory(Node->FullName))) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_REQ), gShellLevel2HiiHandle);
      return (SHELL_INVALID_PARAMETER);
    }

    //
    // make sure got dest as dir if needed
    //
    if (!EFI_ERROR(ShellIsDirectory(Node->FullName)) && EFI_ERROR(ShellIsDirectory(DestDir))) {
      //
      // Error for destination not a directory
      //
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, DestDir);
      return (SHELL_INVALID_PARAMETER);
    }
  }

  HiiOutput   = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_CP_OUTPUT), NULL);
  HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL);
  DestPath    = AllocateZeroPool(PathLen);

  if (DestPath == NULL || HiiOutput == NULL || HiiResultOk == NULL) {
    SHELL_FREE_NON_NULL(DestPath);
    SHELL_FREE_NON_NULL(HiiOutput);
    SHELL_FREE_NON_NULL(HiiResultOk);
    return (SHELL_OUT_OF_RESOURCES);
  }

  //
  // Go through the list of files to copy...
  //
  for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link)
    ;  !IsNull(&FileList->Link, &Node->Link)
    ;  Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link)
    ){
    if (ShellGetExecutionBreakFlag()) {
      break;
    }
    ASSERT(Node->FileName != NULL);
    ASSERT(Node->FullName != NULL);

    //
    // skip the directory traversing stuff...
    //
    if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) {
      continue;
    }

    if (FileList->Link.ForwardLink == FileList->Link.BackLink // 1 item
      && EFI_ERROR(ShellIsDirectory(DestDir))                 // not an existing directory
      ) {
      if (StrStr(DestDir, L":") == NULL) {
        //
        // simple copy of a single file
        //
        StrCpy(DestPath, Cwd);
        if (DestPath[StrLen(DestPath)-1] != L'\\' && DestDir[0] != L'\\') {
          StrCat(DestPath, L"\\");
        } else if (DestPath[StrLen(DestPath)-1] == L'\\' && DestDir[0] == L'\\') {
          ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL;
        }
        StrCat(DestPath, DestDir);
      } else {
        StrCpy(DestPath, DestDir);
      }
    } else {
      //
      // we have multiple files or a directory in the DestDir
      //
      
      //
      // Check for leading slash
      //
      if (DestDir[0] == L'\\') {
          //
          // Copy to the root of CWD
          //
        StrCpy(DestPath, Cwd);
        while (PathRemoveLastItem(DestPath));
        StrCat(DestPath, DestDir+1);
        StrCat(DestPath, Node->FileName);
      } else if (StrStr(DestDir, L":") == NULL) {
        StrCpy(DestPath, Cwd);
        if (DestPath[StrLen(DestPath)-1] != L'\\' && DestDir[0] != L'\\') {
          StrCat(DestPath, L"\\");
        } else if (DestPath[StrLen(DestPath)-1] == L'\\' && DestDir[0] == L'\\') {
          ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL;
        }
        StrCat(DestPath, DestDir);
        if (DestDir[StrLen(DestDir)-1] != L'\\' && Node->FileName[0] != L'\\') {
          StrCat(DestPath, L"\\");
        } else if (DestDir[StrLen(DestDir)-1] == L'\\' && Node->FileName[0] == L'\\') {
          ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL;
        }
        StrCat(DestPath, Node->FileName);

      } else {
        StrCpy(DestPath, DestDir);
        if (DestDir[StrLen(DestDir)-1] != L'\\' && Node->FileName[0] != L'\\') {
          StrCat(DestPath, L"\\");
        } else if (DestDir[StrLen(DestDir)-1] == L'\\' && Node->FileName[0] == L'\\') {
          ((CHAR16*)DestDir)[StrLen(DestDir)-1] = CHAR_NULL;
        }
        StrCat(DestPath, Node->FileName);
      }
    }

    //
    // Make sure the path exists
    //
    if (EFI_ERROR(VerifyIntermediateDirectories(DestPath))) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_WNF), gShellLevel2HiiHandle);
      ShellStatus = SHELL_DEVICE_ERROR;
      break;
    }

    if ( !EFI_ERROR(ShellIsDirectory(Node->FullName))
      && !EFI_ERROR(ShellIsDirectory(DestPath))
      && StrniCmp(Node->FullName, DestPath, StrLen(DestPath)) == NULL
      ){
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_PARENT), gShellLevel2HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
      break;
    }
    if (StringNoCaseCompare(&Node->FullName, &DestPath) == 0) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
      break;
    }

    if ((TempLocation = StrniCmp(Node->FullName, DestPath, StrLen(Node->FullName))) == 0
      && (DestPath[StrLen(Node->FullName)] == CHAR_NULL || DestPath[StrLen(Node->FullName)] == L'\\')
      ) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
      break;
    }

    PathCleanUpDirectories(DestPath);

    ShellPrintEx(-1, -1, HiiOutput, Node->FullName, DestPath);

    //
    // copy single file...
    //
    ShellStatus = CopySingleFile(Node->FullName, DestPath, &Response, SilentMode);
    if (ShellStatus != SHELL_SUCCESS) {
      break;
    }
  }
  if (ShellStatus == SHELL_SUCCESS && Resp == NULL) {
    ShellPrintEx(-1, -1, L"%s", HiiResultOk);
  }

  SHELL_FREE_NON_NULL(DestPath);
  SHELL_FREE_NON_NULL(HiiOutput);
  SHELL_FREE_NON_NULL(HiiResultOk);
  if (Resp == NULL) {
    SHELL_FREE_NON_NULL(Response);
  }

  return (ShellStatus);

}
Exemplo n.º 5
0
Arquivo: If.c Projeto: jeppeter/vbox
/**
  Do a comparison between 2 things.

  @param[in] Compare1           The first item to compare.
  @param[in] Compare2           The second item to compare.
  @param[in] BinOp              The type of comparison to perform.
  @param[in] CaseInsensitive    TRUE to do non-case comparison, FALSE otherwise.
  @param[in] ForceStringCompare TRUE to force string comparison, FALSE otherwise.

  @return     The result of the comparison.
**/
BOOLEAN
EFIAPI
TestOperation (
    IN CONST CHAR16             *Compare1,
    IN CONST CHAR16             *Compare2,
    IN CONST BIN_OPERATOR_TYPE  BinOp,
    IN CONST BOOLEAN            CaseInsensitive,
    IN CONST BOOLEAN            ForceStringCompare
)
{
    INTN Cmp1;
    INTN Cmp2;

    //
    // "Compare1 BinOp Compare2"
    //
    switch (BinOp) {
    case OperatorUnisgnedGreaterThan:
    case OperatorGreaterThan:
        if (ForceStringCompare || !ShellIsHexOrDecimalNumber(Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber(Compare2, FALSE, FALSE)) {
            //
            // string compare
            //
            if ((CaseInsensitive && StringNoCaseCompare(&Compare1, &Compare2) > 0) || (StringCompare(&Compare1, &Compare2) > 0)) {
                return (TRUE);
            }
        } else {
            //
            // numeric compare
            //
            if (Compare1[0] == L'-') {
                Cmp1 = 0 - (INTN)ShellStrToUintn(Compare1+1);
            } else {
                Cmp1 = (INTN)ShellStrToUintn(Compare1);
            }
            if (Compare2[0] == L'-') {
                Cmp2 = 0 - (INTN)ShellStrToUintn(Compare2+1);
            } else {
                Cmp2 = (INTN)ShellStrToUintn(Compare2);
            }
            if (BinOp == OperatorGreaterThan) {
                if (Cmp1 > Cmp2) {
                    return (TRUE);
                }
            } else {
                if ((UINTN)Cmp1 > (UINTN)Cmp2) {
                    return (TRUE);
                }
            }
        }
        return (FALSE);
        break;
    case OperatorUnsignedLessThan:
    case OperatorLessThan:
        if (ForceStringCompare || !ShellIsHexOrDecimalNumber(Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber(Compare2, FALSE, FALSE)) {
            //
            // string compare
            //
            if ((CaseInsensitive && StringNoCaseCompare(&Compare1, &Compare2) < 0) || (StringCompare(&Compare1, &Compare2) < 0)) {
                return (TRUE);
            }
        } else {
            //
            // numeric compare
            //
            if (Compare1[0] == L'-') {
                Cmp1 = 0 - (INTN)ShellStrToUintn(Compare1+1);
            } else {
                Cmp1 = (INTN)ShellStrToUintn(Compare1);
            }
            if (Compare2[0] == L'-') {
                Cmp2 = 0 - (INTN)ShellStrToUintn(Compare2+1);
            } else {
                Cmp2 = (INTN)ShellStrToUintn(Compare2);
            }
            if (BinOp == OperatorLessThan) {
                if (Cmp1 < Cmp2) {
                    return (TRUE);
                }
            } else {
                if ((UINTN)Cmp1 < (UINTN)Cmp2) {
                    return (TRUE);
                }
            }

        }
        return (FALSE);
        break;
    case OperatorEqual:
        if (ForceStringCompare || !ShellIsHexOrDecimalNumber(Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber(Compare2, FALSE, FALSE)) {
            //
            // string compare
            //
            if ((CaseInsensitive && StringNoCaseCompare(&Compare1, &Compare2) == 0) || (StringCompare(&Compare1, &Compare2) == 0)) {
                return (TRUE);
            }
        } else {
            //
            // numeric compare
            //
            if (Compare1[0] == L'-') {
                Cmp1 = 0 - (INTN)ShellStrToUintn(Compare1+1);
            } else {
                Cmp1 = (INTN)ShellStrToUintn(Compare1);
            }
            if (Compare2[0] == L'-') {
                Cmp2 = 0 - (INTN)ShellStrToUintn(Compare2+1);
            } else {
                Cmp2 = (INTN)ShellStrToUintn(Compare2);
            }
            if (Cmp1 == Cmp2) {
                return (TRUE);
            }
        }
        return (FALSE);
        break;
    case OperatorNotEqual:
        if (ForceStringCompare || !ShellIsHexOrDecimalNumber(Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber(Compare2, FALSE, FALSE)) {
            //
            // string compare
            //
            if ((CaseInsensitive && StringNoCaseCompare(&Compare1, &Compare2) != 0) || (StringCompare(&Compare1, &Compare2) != 0)) {
                return (TRUE);
            }
        } else {
            //
            // numeric compare
            //
            if (Compare1[0] == L'-') {
                Cmp1 = 0 - (INTN)ShellStrToUintn(Compare1+1);
            } else {
                Cmp1 = (INTN)ShellStrToUintn(Compare1);
            }
            if (Compare2[0] == L'-') {
                Cmp2 = 0 - (INTN)ShellStrToUintn(Compare2+1);
            } else {
                Cmp2 = (INTN)ShellStrToUintn(Compare2);
            }
            if (Cmp1 != Cmp2) {
                return (TRUE);
            }
        }
        return (FALSE);
        break;
    case OperatorUnsignedGreaterOrEqual:
    case OperatorGreatorOrEqual:
        if (ForceStringCompare || !ShellIsHexOrDecimalNumber(Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber(Compare2, FALSE, FALSE)) {
            //
            // string compare
            //
            if ((CaseInsensitive && StringNoCaseCompare(&Compare1, &Compare2) >= 0) || (StringCompare(&Compare1, &Compare2) >= 0)) {
                return (TRUE);
            }
        } else {
            //
            // numeric compare
            //
            if (Compare1[0] == L'-') {
                Cmp1 = 0 - (INTN)ShellStrToUintn(Compare1+1);
            } else {
                Cmp1 = (INTN)ShellStrToUintn(Compare1);
            }
            if (Compare2[0] == L'-') {
                Cmp2 = 0 - (INTN)ShellStrToUintn(Compare2+1);
            } else {
                Cmp2 = (INTN)ShellStrToUintn(Compare2);
            }
            if (BinOp == OperatorGreatorOrEqual) {
                if (Cmp1 >= Cmp2) {
                    return (TRUE);
                }
            } else {
                if ((UINTN)Cmp1 >= (UINTN)Cmp2) {
                    return (TRUE);
                }
            }
        }
        return (FALSE);
        break;
    case OperatorLessOrEqual:
    case OperatorUnsignedLessOrEqual:
        if (ForceStringCompare || !ShellIsHexOrDecimalNumber(Compare1, FALSE, FALSE) || !ShellIsHexOrDecimalNumber(Compare2, FALSE, FALSE)) {
            //
            // string compare
            //
            if ((CaseInsensitive && StringNoCaseCompare(&Compare1, &Compare2) <= 0) || (StringCompare(&Compare1, &Compare2) <= 0)) {
                return (TRUE);
            }
        } else {
            //
            // numeric compare
            //
            if (Compare1[0] == L'-') {
                Cmp1 = 0 - (INTN)ShellStrToUintn(Compare1+1);
            } else {
                Cmp1 = (INTN)ShellStrToUintn(Compare1);
            }
            if (Compare2[0] == L'-') {
                Cmp2 = 0 - (INTN)ShellStrToUintn(Compare2+1);
            } else {
                Cmp2 = (INTN)ShellStrToUintn(Compare2);
            }
            if (BinOp == OperatorLessOrEqual) {
                if (Cmp1 <= Cmp2) {
                    return (TRUE);
                }
            } else {
                if ((UINTN)Cmp1 <= (UINTN)Cmp2) {
                    return (TRUE);
                }
            }
        }
        return (FALSE);
        break;
    default:
        ASSERT(FALSE);
        return (FALSE);
    }
}