/** Determines if a Node is a valid delete target. Will prevent deleting the root directory. @param[in] List RESERVED. Not used. @param[in] Node The node to analyze. @param[in] Package RESERVED. Not used. **/ BOOLEAN IsValidDeleteTarget( IN CONST EFI_SHELL_FILE_INFO *List, IN CONST EFI_SHELL_FILE_INFO *Node, IN CONST LIST_ENTRY *Package ) { CONST CHAR16 *TempLocation; BOOLEAN RetVal; CHAR16 *SearchString; CHAR16 *Pattern; UINTN Size; if (Node == NULL || Node->FullName == NULL) { return (FALSE); } TempLocation = StrStr(Node->FullName, L":"); if (StrLen(TempLocation) <= 2) { // // Deleting the root directory is invalid. // return (FALSE); } TempLocation = ShellGetCurrentDir(NULL); if (TempLocation == NULL) { // // No working directory is specified so whatever is left is ok. // return (TRUE); } Pattern = NULL; SearchString = NULL; Size = 0; Pattern = StrnCatGrow(&Pattern, &Size, TempLocation , 0); Pattern = StrnCatGrow(&Pattern, &Size, L"\\" , 0); Size = 0; SearchString = StrnCatGrow(&SearchString, &Size, Node->FullName, 0); if (!EFI_ERROR(ShellIsDirectory(SearchString))) { SearchString = StrnCatGrow(&SearchString, &Size, L"\\", 0); SearchString = StrnCatGrow(&SearchString, &Size, L"*", 0); } if (Pattern == NULL || SearchString == NULL) { RetVal = FALSE; } else { RetVal = TRUE; if (gUnicodeCollation->MetaiMatch(gUnicodeCollation, Pattern, SearchString)) { RetVal = FALSE; } } SHELL_FREE_NON_NULL(Pattern ); SHELL_FREE_NON_NULL(SearchString); return (RetVal); }
/** Extract the next fragment, if there is one. @param[in, out] Statement The current remaining statement. @param[in] Fragment The current fragment. @retval FALSE There is not another fragment. @retval TRUE There is another fragment. **/ BOOLEAN EFIAPI IsNextFragment ( IN OUT CONST CHAR16 **Statement, IN CONST CHAR16 *Fragment ) { CHAR16 *Tester; Tester = NULL; Tester = StrnCatGrow(&Tester, NULL, *Statement, StrLen(Fragment)); ASSERT(Tester != NULL); Tester[StrLen(Fragment)] = CHAR_NULL; if (gUnicodeCollation->StriColl( gUnicodeCollation, (CHAR16*)Fragment, Tester) == 0) { // // increment the string pointer to the end of what we found and then chop off spaces... // *Statement+=StrLen(Fragment); while (*Statement[0] == L' ') { (*Statement)++; } FreePool(Tester); return (TRUE); } FreePool(Tester); return (FALSE); }
/** Update the value of a given alias on the list. If the alias is not there then add it. @param[in] Alias The alias to test for. @param[in] CommandString The updated command string. @param[in, out] List The list to search. @retval EFI_SUCCESS The operation was completed successfully. @retval EFI_OUT_OF_RESOURCES There was not enough free memory. **/ EFI_STATUS EFIAPI InternalUpdateAliasOnList( IN CONST CHAR16 *Alias, IN CONST CHAR16 *CommandString, IN OUT LIST_ENTRY *List ) { ALIAS_LIST *Node; BOOLEAN Found; // // assert for NULL parameter // ASSERT(Alias != NULL); // // check for the Alias // for ( Node = (ALIAS_LIST *)GetFirstNode(List), Found = FALSE ; !IsNull(List, &Node->Link) ; Node = (ALIAS_LIST *)GetNextNode(List, &Node->Link) ){ ASSERT(Node->CommandString != NULL); ASSERT(Node->Alias != NULL); if (StrCmp(Node->Alias, Alias)==0) { FreePool(Node->CommandString); Node->CommandString = NULL; Node->CommandString = StrnCatGrow(&Node->CommandString, NULL, CommandString, 0); Found = TRUE; break; } } if (!Found) { Node = AllocateZeroPool(sizeof(ALIAS_LIST)); if (Node == NULL) { return (EFI_OUT_OF_RESOURCES); } ASSERT(Node->Alias == NULL); Node->Alias = StrnCatGrow(&Node->Alias, NULL, Alias, 0); ASSERT(Node->CommandString == NULL); Node->CommandString = StrnCatGrow(&Node->CommandString, NULL, CommandString, 0); InsertTailList(List, &Node->Link); } return (EFI_SUCCESS); }
/** returns a fully qualified directory (contains a map drive at the begining) path from a unknown directory path. If Path is already fully qualified this will return a duplicat otherwise this will use get the current directory and use that to build the fully qualified version. if the return value is not NULL it must be caller freed. @param[in] Path The unknown Path Value @retval NULL A memory allocation failed @retval NULL A fully qualified path could not be discovered. @retval other An allocated pointer to a fuly qualified path. **/ CHAR16* GetFullyQualifiedPath( IN CONST CHAR16* Path ) { CHAR16 *PathToReturn; UINTN Size; CONST CHAR16 *CurDir; PathToReturn = NULL; Size = 0; ASSERT((PathToReturn == NULL && Size == 0) || (PathToReturn != NULL)); // // convert a local path to an absolute path // if (StrStr(Path, L":") == NULL) { CurDir = gEfiShellProtocol->GetCurDir(NULL); StrnCatGrow(&PathToReturn, &Size, CurDir, 0); StrnCatGrow(&PathToReturn, &Size, L"\\", 0); if (*Path == L'\\') { Path++; } } StrnCatGrow(&PathToReturn, &Size, Path, 0); PathCleanUpDirectories(PathToReturn); if (PathToReturn == NULL) { return NULL; } while (PathToReturn[StrLen(PathToReturn)-1] == L'*') { PathToReturn[StrLen(PathToReturn)-1] = CHAR_NULL; } return (PathToReturn); }
/** Function to verify all intermediate directories in the path. @param[in] Path The pointer to the path to fix. @retval EFI_SUCCESS The operation was successful. **/ EFI_STATUS EFIAPI VerifyIntermediateDirectories ( IN CONST CHAR16 *Path ) { EFI_STATUS Status; CHAR16 *PathCopy; CHAR16 *TempSpot; SHELL_FILE_HANDLE FileHandle; ASSERT(Path != NULL); Status = EFI_SUCCESS; PathCopy = NULL; PathCopy = StrnCatGrow(&PathCopy, NULL, Path, 0); FileHandle = NULL; if (PathCopy == NULL) { return (EFI_OUT_OF_RESOURCES); } for (TempSpot = &PathCopy[StrLen(PathCopy)-1] ; *TempSpot != CHAR_NULL && *TempSpot != L'\\' ; TempSpot = &PathCopy[StrLen(PathCopy)-1]){ *TempSpot = CHAR_NULL; } if (*TempSpot == L'\\') { *TempSpot = CHAR_NULL; } if (PathCopy != NULL && *PathCopy != CHAR_NULL) { Status = VerifyIntermediateDirectories(PathCopy); if (PathCopy[StrLen(PathCopy)-1] != L':') { if (!EFI_ERROR(Status)) { Status = ShellOpenFileByName(PathCopy, &FileHandle, EFI_FILE_MODE_READ, 0); if (FileHandle != NULL) { ShellCloseFile(&FileHandle); } } } } SHELL_FREE_NON_NULL(PathCopy); return (Status); }
/** Validate and if successful copy all the files from the list into destination directory. @param[in] FileList The list of files to copy. @param[in] DestDir The directory to copy files to. @param[in] SilentMode TRUE to eliminate screen output. @param[in] RecursiveMode TRUE to copy directories. @retval SHELL_INVALID_PARAMETER A parameter was invalid. @retval SHELL_SUCCESS The operation was successful. **/ SHELL_STATUS EFIAPI ProcessValidateAndCopyFiles( IN EFI_SHELL_FILE_INFO *FileList, IN CONST CHAR16 *DestDir, IN BOOLEAN SilentMode, IN BOOLEAN RecursiveMode ) { SHELL_STATUS ShellStatus; EFI_SHELL_FILE_INFO *List; EFI_FILE_INFO *FileInfo; CHAR16 *FullName; List = NULL; FullName = NULL; FileInfo = NULL; ShellOpenFileMetaArg((CHAR16*)DestDir, EFI_FILE_MODE_READ, &List); if (List != NULL && List->Link.ForwardLink != List->Link.BackLink) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, DestDir); ShellStatus = SHELL_INVALID_PARAMETER; ShellCloseFileMetaArg(&List); } else if (List != NULL) { ASSERT(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink) != NULL); ASSERT(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName != NULL); FileInfo = gEfiShellProtocol->GetFileInfo(((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->Handle); ASSERT(FileInfo != NULL); StrnCatGrow(&FullName, NULL, ((EFI_SHELL_FILE_INFO *)List->Link.ForwardLink)->FullName, 0); ShellCloseFileMetaArg(&List); if ((FileInfo->Attribute & EFI_FILE_READ_ONLY) == 0) { ShellStatus = ValidateAndCopyFiles(FileList, FullName, SilentMode, RecursiveMode, NULL); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DEST_ERROR), gShellLevel2HiiHandle); ShellStatus = SHELL_ACCESS_DENIED; } } else { ShellCloseFileMetaArg(&List); ShellStatus = ValidateAndCopyFiles(FileList, DestDir, SilentMode, RecursiveMode, NULL); } SHELL_FREE_NON_NULL(FileInfo); SHELL_FREE_NON_NULL(FullName); return (ShellStatus); }
/** Get the name of a driver by it's handle. If a name is found the memory must be callee freed. @param[in] TheHandle The driver's handle. @param[in] Language The language to use. @param[in] NameFound Upon a successful return the name found. @retval EFI_SUCCESS The name was found. **/ EFI_STATUS EFIAPI GetDriverName ( IN EFI_HANDLE TheHandle, IN CONST CHAR8 *Language, IN CHAR16 **NameFound ) { CHAR8 *Lang; EFI_STATUS Status; EFI_COMPONENT_NAME2_PROTOCOL *CompName2; CHAR16 *NameToReturn; // // Go through those handles until we get one that passes for GetComponentName // Status = gBS->OpenProtocol( TheHandle, &gEfiComponentName2ProtocolGuid, (VOID**)&CompName2, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(Status)) { Status = gBS->OpenProtocol( TheHandle, &gEfiComponentNameProtocolGuid, (VOID**)&CompName2, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); } if (EFI_ERROR(Status)) { return (EFI_NOT_FOUND); } Lang = GetBestLanguageForDriver (CompName2->SupportedLanguages, Language, FALSE); Status = CompName2->GetDriverName(CompName2, Lang, &NameToReturn); FreePool(Lang); if (!EFI_ERROR(Status) && NameToReturn != NULL) { *NameFound = NULL; StrnCatGrow(NameFound, NULL, NameToReturn, 0); } return (Status); }
EFIAPI GetAttrType ( IN CONST UINT32 Atts ) { UINTN BufLen; CHAR16 *RetString; BufLen = 0; RetString = NULL; if ((Atts & EFI_VARIABLE_NON_VOLATILE) != 0) { StrnCatGrow (&RetString, &BufLen, L"+NV", 0); } if ((Atts & EFI_VARIABLE_RUNTIME_ACCESS) != 0) { StrnCatGrow (&RetString, &BufLen, L"+RS+BS", 0); } else if ((Atts & EFI_VARIABLE_BOOTSERVICE_ACCESS) != 0) { StrnCatGrow (&RetString, &BufLen, L"+BS", 0); } if ((Atts & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) { StrnCatGrow (&RetString, &BufLen, L"+HR", 0); } if ((Atts & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) { StrnCatGrow (&RetString, &BufLen, L"+AW", 0); } if ((Atts & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) { StrnCatGrow (&RetString, &BufLen, L"+AT", 0); } if (RetString == NULL) { RetString = StrnCatGrow(&RetString, &BufLen, L"Invalid", 0); } if ((RetString != NULL) && (RetString[0] == L'+')) { CopyMem(RetString, RetString + 1, StrSize(RetString + 1)); } return RetString; }
/** parses through the MAN file specified by SHELL_FILE_HANDLE and returns the detailed help for any sub section specified in the comma seperated list of sections provided. If the end of the file or a .TH section is found then return. Upon a sucessful return the caller is responsible to free the memory in *HelpText @param[in] Handle FileHandle to read from @param[in] Sections name of command's sub sections to find @param[out] HelpText pointer to pointer to string where text goes. @param[out] HelpSize pointer to size of allocated HelpText (may be updated) @param[in] Ascii TRUE if the file is ASCII, FALSE otherwise. @retval EFI_OUT_OF_RESOURCES a memory allocation failed. @retval EFI_SUCCESS the section was found and its description sotred in an alloceted buffer. **/ EFI_STATUS EFIAPI ManFileFindSections( IN SHELL_FILE_HANDLE Handle, IN CONST CHAR16 *Sections, OUT CHAR16 **HelpText, OUT UINTN *HelpSize, IN BOOLEAN Ascii ) { EFI_STATUS Status; CHAR16 *ReadLine; UINTN Size; BOOLEAN CurrentlyReading; CHAR16 *SectionName; UINTN SectionLen; BOOLEAN Found; if ( Handle == NULL || HelpText == NULL || HelpSize == NULL ){ return (EFI_INVALID_PARAMETER); } Status = EFI_SUCCESS; CurrentlyReading = FALSE; Size = 1024; Found = FALSE; ReadLine = AllocateZeroPool(Size); if (ReadLine == NULL) { return (EFI_OUT_OF_RESOURCES); } for (;!ShellFileHandleEof(Handle);Size = 1024) { Status = ShellFileHandleReadLine(Handle, ReadLine, &Size, TRUE, &Ascii); if (ReadLine[0] == L'#') { // // Skip comment lines // continue; } // // ignore too small of buffer... // if (Status == EFI_BUFFER_TOO_SMALL) { Status = EFI_SUCCESS; } if (EFI_ERROR(Status)) { break; } else if (StrnCmp(ReadLine, L".TH", 3) == 0) { // // we hit the end of this commands section so stop. // break; } else if (StrnCmp(ReadLine, L".SH", 3) == 0) { if (Sections == NULL) { CurrentlyReading = TRUE; continue; } // // we found a section // if (CurrentlyReading) { CurrentlyReading = FALSE; } // // is this a section we want to read in? // for ( SectionName = ReadLine + 3 ; *SectionName == L' ' ; SectionName++); SectionLen = StrLen(SectionName); SectionName = StrStr(Sections, SectionName); if (SectionName == NULL) { continue; } if (*(SectionName + SectionLen) == CHAR_NULL || *(SectionName + SectionLen) == L',') { CurrentlyReading = TRUE; } } else if (CurrentlyReading) { Found = TRUE; // // copy and save the current line. // ASSERT((*HelpText == NULL && *HelpSize == 0) || (*HelpText != NULL)); StrnCatGrow (HelpText, HelpSize, ReadLine, 0); StrnCatGrow (HelpText, HelpSize, L"\r\n", 0); } } FreePool(ReadLine); if (!Found && !EFI_ERROR(Status)) { return (EFI_NOT_FOUND); } return (Status); }
/** Get information for a handle. @param[in] TheHandle The handles to show info on. @param[in] Language Language string per UEFI specification. @param[in] Separator Separator string between information blocks. @param[in] Verbose TRUE for extra info, FALSE otherwise. @param[in] ExtraInfo TRUE for extra info, FALSE otherwise. @retval SHELL_SUCCESS The operation was successful. @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid. **/ CHAR16* GetProtocolInfoString( IN CONST EFI_HANDLE TheHandle, IN CONST CHAR8 *Language, IN CONST CHAR16 *Separator, IN CONST BOOLEAN Verbose, IN CONST BOOLEAN ExtraInfo ) { EFI_GUID **ProtocolGuidArray; UINTN ArrayCount; UINTN ProtocolIndex; EFI_STATUS Status; CHAR16 *RetVal; UINTN Size; CHAR16 *Temp; CHAR16 GuidStr[40]; ProtocolGuidArray = NULL; RetVal = NULL; Size = 0; Status = gBS->ProtocolsPerHandle ( TheHandle, &ProtocolGuidArray, &ArrayCount ); if (!EFI_ERROR (Status)) { for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) { Temp = GetStringNameFromGuid(ProtocolGuidArray[ProtocolIndex], Language); ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL)); if (Size != 0) { StrnCatGrow(&RetVal, &Size, Separator, 0); } StrnCatGrow(&RetVal, &Size, L"%H", 0); if (Temp == NULL) { UnicodeSPrint (GuidStr, sizeof (GuidStr), L"%g", ProtocolGuidArray[ProtocolIndex]); StrnCatGrow (&RetVal, &Size, GuidStr, 0); } else { StrnCatGrow(&RetVal, &Size, Temp, 0); FreePool(Temp); } StrnCatGrow(&RetVal, &Size, L"%N", 0); if (ExtraInfo) { Temp = GetProtocolInformationDump(TheHandle, ProtocolGuidArray[ProtocolIndex], Verbose); if (Temp != NULL) { ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL)); if (!Verbose) { StrnCatGrow(&RetVal, &Size, L"(", 0); StrnCatGrow(&RetVal, &Size, Temp, 0); StrnCatGrow(&RetVal, &Size, L")\r\n", 0); } else { StrnCatGrow(&RetVal, &Size, Separator, 0); StrnCatGrow(&RetVal, &Size, Temp, 0); } FreePool(Temp); } } } } SHELL_FREE_NON_NULL(ProtocolGuidArray); if (RetVal == NULL) { return (NULL); } ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL)); StrnCatGrow(&RetVal, &Size, Separator, 0); return (RetVal); }
/** Function for 'ls' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunLs ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; CONST CHAR16 *Attribs; SHELL_STATUS ShellStatus; UINT64 RequiredAttributes; CONST CHAR16 *PathName; CONST CHAR16 *CurDir; UINTN Count; CHAR16 *FullPath; UINTN Size; EFI_TIME TheTime; CHAR16 *SearchString; Size = 0; FullPath = NULL; ProblemParam = NULL; Attribs = NULL; ShellStatus = SHELL_SUCCESS; RequiredAttributes = 0; PathName = NULL; SearchString = NULL; CurDir = NULL; Count = 0; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); // // Fix local copies of the protocol pointers // Status = CommandInit(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (LsParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"ls", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { // // check for "-?" // if (ShellCommandLineGetFlag(Package, L"-?")) { ASSERT(FALSE); } if (ShellCommandLineGetCount(Package) > 2) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"ls"); ShellStatus = SHELL_INVALID_PARAMETER; } else { // // check for -a // if (ShellCommandLineGetFlag(Package, L"-a")) { for ( Attribs = ShellCommandLineGetValue(Package, L"-a") ; Attribs != NULL && *Attribs != CHAR_NULL && ShellStatus == SHELL_SUCCESS ; Attribs++ ){ switch (*Attribs) { case L'a': case L'A': RequiredAttributes |= EFI_FILE_ARCHIVE; Count++; continue; case L's': case L'S': RequiredAttributes |= EFI_FILE_SYSTEM; Count++; continue; case L'h': case L'H': RequiredAttributes |= EFI_FILE_HIDDEN; Count++; continue; case L'r': case L'R': RequiredAttributes |= EFI_FILE_READ_ONLY; Count++; continue; case L'd': case L'D': RequiredAttributes |= EFI_FILE_DIRECTORY; Count++; continue; default: ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ATTRIBUTE), gShellLevel2HiiHandle, L"ls", ShellCommandLineGetValue(Package, L"-a")); ShellStatus = SHELL_INVALID_PARAMETER; break; } // switch } // for loop // // if nothing is specified all are specified // if (RequiredAttributes == 0) { RequiredAttributes = EFI_FILE_VALID_ATTR; } } // if -a present if (ShellStatus == SHELL_SUCCESS) { PathName = ShellCommandLineGetRawValue(Package, 1); if (PathName == NULL) { // // Nothing specified... must start from current directory // CurDir = gEfiShellProtocol->GetCurDir(NULL); if (CurDir == NULL) { ShellStatus = SHELL_NOT_FOUND; ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"ls"); } // // Copy to the 2 strings for starting path and file search string // ASSERT(SearchString == NULL); ASSERT(FullPath == NULL); StrnCatGrow(&SearchString, NULL, L"*", 0); StrnCatGrow(&FullPath, NULL, CurDir, 0); Size = FullPath != NULL? StrSize(FullPath) : 0; StrnCatGrow(&FullPath, &Size, L"\\", 0); } else { if (StrStr(PathName, L":") == NULL && gEfiShellProtocol->GetCurDir(NULL) == NULL) { // // If we got something and it doesnt have a fully qualified path, then we needed to have a CWD. // ShellStatus = SHELL_NOT_FOUND; ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"ls"); } else { // // We got a valid fully qualified path or we have a CWD // ASSERT((FullPath == NULL && Size == 0) || (FullPath != NULL)); if (StrStr(PathName, L":") == NULL) { StrnCatGrow(&FullPath, &Size, gEfiShellProtocol->GetCurDir(NULL), 0); if (FullPath == NULL) { ShellCommandLineFreeVarList (Package); return SHELL_OUT_OF_RESOURCES; } Size = FullPath != NULL? StrSize(FullPath) : 0; StrnCatGrow(&FullPath, &Size, L"\\", 0); } StrnCatGrow(&FullPath, &Size, PathName, 0); if (FullPath == NULL) { ShellCommandLineFreeVarList (Package); return SHELL_OUT_OF_RESOURCES; } if (ShellIsDirectory(PathName) == EFI_SUCCESS) { // // is listing ends with a directory, then we list all files in that directory // StrnCatGrow(&SearchString, NULL, L"*", 0); } else { // // must split off the search part that applies to files from the end of the directory part // StrnCatGrow(&SearchString, NULL, FullPath, 0); if (SearchString == NULL) { FreePool (FullPath); ShellCommandLineFreeVarList (Package); return SHELL_OUT_OF_RESOURCES; } PathRemoveLastItem (FullPath); CopyMem (SearchString, SearchString + StrLen (FullPath), StrSize (SearchString + StrLen (FullPath))); } } } Status = gRT->GetTime(&TheTime, NULL); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"ls", L"gRT->GetTime", Status); TheTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE; } if (ShellStatus == SHELL_SUCCESS) { ShellStatus = PrintLsOutput( ShellCommandLineGetFlag(Package, L"-r"), RequiredAttributes, ShellCommandLineGetFlag(Package, L"-sfo"), FullPath, SearchString, NULL, Count, TheTime.TimeZone ); if (ShellStatus == SHELL_NOT_FOUND) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LS_FILE_NOT_FOUND), gShellLevel2HiiHandle, L"ls", FullPath); } else if (ShellStatus == SHELL_INVALID_PARAMETER) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"ls", FullPath); } else if (ShellStatus == SHELL_ABORTED) { // // Ignore aborting. // } else if (ShellStatus != SHELL_SUCCESS) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"ls", FullPath); } } } } } // // Free memory allocated // SHELL_FREE_NON_NULL(SearchString); SHELL_FREE_NON_NULL(FullPath); ShellCommandLineFreeVarList (Package); return (ShellStatus); }
/** parses through Buffer (which is MAN file formatted) and returns the detailed help for any sub section specified in the comma seperated list of sections provided. If the end of the file or a .TH section is found then return. Upon a sucessful return the caller is responsible to free the memory in *HelpText @param[in] Buffer Buffer to read from @param[in] Sections name of command's sub sections to find @param[in] HelpText pointer to pointer to string where text goes. @param[in] HelpSize pointer to size of allocated HelpText (may be updated) @retval EFI_OUT_OF_RESOURCES a memory allocation failed. @retval EFI_SUCCESS the section was found and its description sotred in an alloceted buffer. **/ EFI_STATUS EFIAPI ManBufferFindSections( IN CONST CHAR16 *Buffer, IN CONST CHAR16 *Sections, IN CHAR16 **HelpText, IN UINTN *HelpSize ) { EFI_STATUS Status; CONST CHAR16 *CurrentLocation; BOOLEAN CurrentlyReading; CHAR16 *SectionName; UINTN SectionLen; BOOLEAN Found; CHAR16 *TempString; CHAR16 *TempString2; if ( Buffer == NULL || HelpText == NULL || HelpSize == NULL ){ return (EFI_INVALID_PARAMETER); } Status = EFI_SUCCESS; CurrentlyReading = FALSE; Found = FALSE; for (CurrentLocation = Buffer,TempString = NULL ; CurrentLocation != NULL && *CurrentLocation != CHAR_NULL ; CurrentLocation=StrStr(CurrentLocation, L"\r\n"),TempString = NULL ){ while(CurrentLocation[0] == L'\r' || CurrentLocation[0] == L'\n') { CurrentLocation++; } if (CurrentLocation[0] == L'#') { // // Skip comment lines // continue; } if (StrnCmp(CurrentLocation, L".TH", 3) == 0) { // // we hit the end of this commands section so stop. // break; } if (StrnCmp(CurrentLocation, L".SH ", 4) == 0) { if (Sections == NULL) { CurrentlyReading = TRUE; continue; } else if (CurrentlyReading) { CurrentlyReading = FALSE; } CurrentLocation += 4; // // is this a section we want to read in? // if (StrLen(CurrentLocation)!=0) { TempString2 = StrStr(CurrentLocation, L" "); TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\r")); TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\n")); ASSERT(TempString == NULL); TempString = StrnCatGrow(&TempString, NULL, CurrentLocation, TempString2==NULL?0:TempString2 - CurrentLocation); if (TempString == NULL) { Status = EFI_OUT_OF_RESOURCES; break; } SectionName = TempString; SectionLen = StrLen(SectionName); SectionName = StrStr(Sections, SectionName); if (SectionName == NULL) { continue; } if (*(SectionName + SectionLen) == CHAR_NULL || *(SectionName + SectionLen) == L',') { CurrentlyReading = TRUE; } } } else if (CurrentlyReading) { Found = TRUE; if (StrLen(CurrentLocation)!=0) { TempString2 = StrStr(CurrentLocation, L"\r"); TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\n")); ASSERT(TempString == NULL); TempString = StrnCatGrow(&TempString, NULL, CurrentLocation, TempString2==NULL?0:TempString2 - CurrentLocation); if (TempString == NULL) { Status = EFI_OUT_OF_RESOURCES; break; } // // copy and save the current line. // ASSERT((*HelpText == NULL && *HelpSize == 0) || (*HelpText != NULL)); StrnCatGrow (HelpText, HelpSize, TempString, 0); if (HelpText == NULL) { Status = EFI_OUT_OF_RESOURCES; break; } StrnCatGrow (HelpText, HelpSize, L"\r\n", 0); if (HelpText == NULL) { Status = EFI_OUT_OF_RESOURCES; break; } } } SHELL_FREE_NON_NULL(TempString); } if (!Found && !EFI_ERROR(Status)) { return (EFI_NOT_FOUND); } return (Status); }
/** Get the name of a driver by it's handle. If a name is found the memory must be callee freed. @param[in] TheHandle The driver's handle. @param[in] Language The language to use. @param[in] NameFound Upon a successful return the name found. @retval EFI_SUCCESS The name was found. **/ EFI_STATUS EFIAPI GetDriverName ( IN EFI_HANDLE TheHandle, IN CONST CHAR8 *Language, IN CHAR16 **NameFound ) { CHAR8 *Lang; CHAR8 *TempChar; EFI_STATUS Status; EFI_COMPONENT_NAME2_PROTOCOL *CompName2; CHAR16 *NameToReturn; // // Go through those handles until we get one that passes for GetComponentName // Status = gBS->OpenProtocol( TheHandle, &gEfiComponentName2ProtocolGuid, (VOID**)&CompName2, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(Status)) { Status = gBS->OpenProtocol( TheHandle, &gEfiComponentNameProtocolGuid, (VOID**)&CompName2, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); } if (EFI_ERROR(Status)) { return (EFI_NOT_FOUND); } if (Language == NULL) { Lang = AllocateZeroPool(AsciiStrSize(CompName2->SupportedLanguages)); if (Lang == NULL) { return (EFI_OUT_OF_RESOURCES); } AsciiStrCpy(Lang, CompName2->SupportedLanguages); TempChar = AsciiStrStr(Lang, ";"); if (TempChar != NULL) { *TempChar = CHAR_NULL; } } else { Lang = AllocateZeroPool(AsciiStrSize(Language)); if (Lang == NULL) { return (EFI_OUT_OF_RESOURCES); } AsciiStrCpy(Lang, Language); } Status = CompName2->GetDriverName(CompName2, Lang, &NameToReturn); FreePool(Lang); if (!EFI_ERROR(Status) && NameToReturn != NULL) { *NameFound = NULL; StrnCatGrow(NameFound, NULL, NameToReturn, 0); } return (Status); }
/** print out the list of files and directories from the LS command @param[in] Rec TRUE to automatically recurse into each found directory FALSE to only list the specified directory. @param[in] Attribs List of required Attribute for display. If 0 then all non-system and non-hidden files will be printed. @param[in] Sfo TRUE to use Standard Format Output, FALSE otherwise @param[in] RootPath String with starting path to search in. @param[in] SearchString String with search string. @param[in] Found Set to TRUE, if anyone were found. @param[in] Count The count of bits enabled in Attribs. @param[in] TimeZone The current time zone offset. @retval SHELL_SUCCESS the printing was sucessful. **/ SHELL_STATUS PrintLsOutput( IN CONST BOOLEAN Rec, IN CONST UINT64 Attribs, IN CONST BOOLEAN Sfo, IN CONST CHAR16 *RootPath, IN CONST CHAR16 *SearchString, IN BOOLEAN *Found, IN CONST UINTN Count, IN CONST INT16 TimeZone ) { EFI_STATUS Status; EFI_SHELL_FILE_INFO *ListHead; EFI_SHELL_FILE_INFO *Node; SHELL_STATUS ShellStatus; UINT64 FileCount; UINT64 DirCount; UINT64 FileSize; UINTN LongestPath; CHAR16 *CorrectedPath; BOOLEAN FoundOne; BOOLEAN HeaderPrinted; EFI_TIME LocalTime; HeaderPrinted = FALSE; FileCount = 0; DirCount = 0; FileSize = 0; ListHead = NULL; ShellStatus = SHELL_SUCCESS; LongestPath = 0; CorrectedPath = NULL; if (Found != NULL) { FoundOne = *Found; } else { FoundOne = FALSE; } CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, RootPath, 0); if (CorrectedPath == NULL) { return SHELL_OUT_OF_RESOURCES; } if (CorrectedPath[StrLen(CorrectedPath)-1] != L'\\' &&CorrectedPath[StrLen(CorrectedPath)-1] != L'/') { CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, L"\\", 0); } CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, SearchString, 0); if (CorrectedPath == NULL) { return (SHELL_OUT_OF_RESOURCES); } PathCleanUpDirectories(CorrectedPath); Status = ShellOpenFileMetaArg((CHAR16*)CorrectedPath, EFI_FILE_MODE_READ, &ListHead); if (!EFI_ERROR(Status)) { if (ListHead == NULL || IsListEmpty(&ListHead->Link)) { SHELL_FREE_NON_NULL(CorrectedPath); return (SHELL_SUCCESS); } if (Sfo && Found == NULL) { PrintSfoVolumeInfoTableEntry(ListHead); } for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&ListHead->Link), LongestPath = 0 ; !IsNull(&ListHead->Link, &Node->Link) ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&ListHead->Link, &Node->Link) ){ if (ShellGetExecutionBreakFlag ()) { ShellStatus = SHELL_ABORTED; break; } ASSERT(Node != NULL); // // Change the file time to local time. // Status = gRT->GetTime(&LocalTime, NULL); if (!EFI_ERROR (Status)) { if ((Node->Info->CreateTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) && (Node->Info->CreateTime.Month >= 1 && Node->Info->CreateTime.Month <= 12)) { // // FileTimeToLocalTime () requires Month is in a valid range, other buffer out-of-band access happens. // FileTimeToLocalTime (&Node->Info->CreateTime, LocalTime.TimeZone); } if ((Node->Info->LastAccessTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) && (Node->Info->LastAccessTime.Month >= 1 && Node->Info->LastAccessTime.Month <= 12)) { FileTimeToLocalTime (&Node->Info->LastAccessTime, LocalTime.TimeZone); } if ((Node->Info->ModificationTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) && (Node->Info->ModificationTime.Month >= 1 && Node->Info->ModificationTime.Month <= 12)) { FileTimeToLocalTime (&Node->Info->ModificationTime, LocalTime.TimeZone); } } if (LongestPath < StrSize(Node->FullName)) { LongestPath = StrSize(Node->FullName); } ASSERT(Node->Info != NULL); ASSERT((Node->Info->Attribute & EFI_FILE_VALID_ATTR) == Node->Info->Attribute); if (Attribs == 0) { // // NOT system & NOT hidden // if ( (Node->Info->Attribute & EFI_FILE_SYSTEM) || (Node->Info->Attribute & EFI_FILE_HIDDEN) ){ continue; } } else if ((Attribs != EFI_FILE_VALID_ATTR) || (Count == 5)) { // // Only matches the bits which "Attribs" contains, not // all files/directories with any of the bits. // Count == 5 is used to tell the difference between a user // specifying all bits (EX: -arhsda) and just specifying // -a (means display all files with any attribute). // if ( (Node->Info->Attribute & Attribs) != Attribs) { continue; } } if (!Sfo && !HeaderPrinted) { PathRemoveLastItem (CorrectedPath); PrintNonSfoHeader(CorrectedPath); } PrintFileInformation(Sfo, Node, &FileCount, &FileSize, &DirCount); FoundOne = TRUE; HeaderPrinted = TRUE; } if (!Sfo && ShellStatus != SHELL_ABORTED) { PrintNonSfoFooter(FileCount, FileSize, DirCount); } } if (Rec && ShellStatus != SHELL_ABORTED) { // // Re-Open all the files under the starting path for directories that didnt necessarily match our file filter // ShellCloseFileMetaArg(&ListHead); CorrectedPath[0] = CHAR_NULL; CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, RootPath, 0); if (CorrectedPath == NULL) { return SHELL_OUT_OF_RESOURCES; } if (CorrectedPath[StrLen(CorrectedPath)-1] != L'\\' &&CorrectedPath[StrLen(CorrectedPath)-1] != L'/') { CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, L"\\", 0); } CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, L"*", 0); Status = ShellOpenFileMetaArg((CHAR16*)CorrectedPath, EFI_FILE_MODE_READ, &ListHead); if (!EFI_ERROR(Status)) { for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&ListHead->Link) ; !IsNull(&ListHead->Link, &Node->Link) && ShellStatus == SHELL_SUCCESS ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&ListHead->Link, &Node->Link) ){ if (ShellGetExecutionBreakFlag ()) { ShellStatus = SHELL_ABORTED; break; } // // recurse on any directory except the traversing ones... // if (((Node->Info->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) && StrCmp(Node->FileName, L".") != 0 && StrCmp(Node->FileName, L"..") != 0 ){ ShellStatus = PrintLsOutput( Rec, Attribs, Sfo, Node->FullName, SearchString, &FoundOne, Count, TimeZone); // // Since it's running recursively, we have to break immediately when returned SHELL_ABORTED // if (ShellStatus == SHELL_ABORTED) { break; } } } } } SHELL_FREE_NON_NULL(CorrectedPath); ShellCloseFileMetaArg(&ListHead); if (Found == NULL && !FoundOne) { return (SHELL_NOT_FOUND); } if (Found != NULL) { *Found = FoundOne; } return (ShellStatus); }
/** Touch a given file and potantially recurse down if it was a directory. @param[in] Name The name of this file. @param[in] FS The name of the file system this file is on. @param[in] Handle The handle of this file already opened. @param[in] Rec TRUE to recurse if possible. @retval EFI_INVALID_PARAMETER A parameter was invalid. @retval EFI_SUCCESS The operation was successful. **/ EFI_STATUS EFIAPI DoTouchByHandle ( IN CONST CHAR16 *Name, IN CHAR16 *FS, IN SHELL_FILE_HANDLE Handle, IN BOOLEAN Rec ) { EFI_STATUS Status; EFI_SHELL_FILE_INFO *FileList; EFI_SHELL_FILE_INFO *Walker; CHAR16 *TempSpot; Status = EFI_SUCCESS; FileList = NULL; Walker = NULL; if (FS == NULL) { FS = StrnCatGrow(&FS, NULL, Name, 0); if (FS != NULL) { TempSpot = StrStr(FS, L"\\"); if (TempSpot != NULL) { *TempSpot = CHAR_NULL; } } } if (FS == NULL) { return (EFI_INVALID_PARAMETER); } // // do it // Status = TouchFileByHandle(Handle); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel3HiiHandle, L"touch", Name); return (Status); } // // if it's a directory recurse... // if (FileHandleIsDirectory(Handle) == EFI_SUCCESS && Rec) { // // get each file under this directory // if (EFI_ERROR(gEfiShellProtocol->FindFilesInDir(Handle, &FileList))) { Status = EFI_INVALID_PARAMETER; } // // recurse on each // for (Walker = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link) ; FileList != NULL && !IsNull(&FileList->Link, &Walker->Link) && !EFI_ERROR(Status) ; Walker = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Walker->Link) ){ if ( (StrCmp(Walker->FileName, L".") != 0) && (StrCmp(Walker->FileName, L"..") != 0) ){ // // Open the file since we need that handle. // Status = gEfiShellProtocol->OpenFileByName (Walker->FullName, &Walker->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel3HiiHandle, L"touch", Walker->FullName); Status = EFI_ACCESS_DENIED; } else { Status = DoTouchByHandle(Walker->FullName, FS, Walker->Handle, TRUE); gEfiShellProtocol->CloseFile(Walker->Handle); Walker->Handle = NULL; } } } // // free stuff // if (FileList != NULL && EFI_ERROR(gEfiShellProtocol->FreeFileList(&FileList))) { Status = EFI_INVALID_PARAMETER; } } return (Status); }
/** Process an if statement and determine if its is valid or not. @param[in, out] PassingState Opon entry, the current state. Upon exit, the new state. @param[in] StartParameterNumber The number of the first parameter of this statement. @param[in] EndParameterNumber The number of the final parameter of this statement. @param[in] OperatorToUse The type of termination operator. @param[in] CaseInsensitive TRUE for case insensitive, FALSE otherwise. @param[in] ForceStringCompare TRUE for all string based, FALSE otherwise. @retval EFI_INVALID_PARAMETER A parameter was invalid. @retval EFI_SUCCESS The operation was successful. **/ EFI_STATUS EFIAPI ProcessStatement ( IN OUT BOOLEAN *PassingState, IN UINTN StartParameterNumber, IN UINTN EndParameterNumber, IN CONST END_TAG_TYPE OperatorToUse, IN CONST BOOLEAN CaseInsensitive, IN CONST BOOLEAN ForceStringCompare ) { EFI_STATUS Status; BOOLEAN OperationResult; BOOLEAN NotPresent; CHAR16 *StatementWalker; BIN_OPERATOR_TYPE BinOp; CHAR16 *Compare1; CHAR16 *Compare2; CHAR16 HexString[20]; CHAR16 *TempSpot; ASSERT((END_TAG_TYPE)OperatorToUse != EndTagThen); Status = EFI_SUCCESS; BinOp = OperatorMax; OperationResult = FALSE; StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber]; if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"not")) { NotPresent = TRUE; StatementWalker = gEfiShellParametersProtocol->Argv[++StartParameterNumber]; } else { NotPresent = FALSE; } // // now check for 'boolfunc' operators // if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"isint")) { if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && StatementWalker[StrLen(StatementWalker)-1] == L')') { StatementWalker[StrLen(StatementWalker)-1] = CHAR_NULL; OperationResult = ShellIsHexOrDecimalNumber(StatementWalker, FALSE, FALSE); } else { Status = EFI_INVALID_PARAMETER; ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"isint"); } } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"exists") || IsNextFragment((CONST CHAR16**)(&StatementWalker), L"exist")) { if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && StatementWalker[StrLen(StatementWalker)-1] == L')') { StatementWalker[StrLen(StatementWalker)-1] = CHAR_NULL; // // is what remains a file in CWD??? // OperationResult = (BOOLEAN)(ShellFileExists(StatementWalker)==EFI_SUCCESS); } else if (StatementWalker[0] == CHAR_NULL && StartParameterNumber+1 == EndParameterNumber) { OperationResult = (BOOLEAN)(ShellFileExists(gEfiShellParametersProtocol->Argv[++StartParameterNumber])==EFI_SUCCESS); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"exist(s)"); Status = EFI_INVALID_PARAMETER; } } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"available")) { if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && StatementWalker[StrLen(StatementWalker)-1] == L')') { StatementWalker[StrLen(StatementWalker)-1] = CHAR_NULL; // // is what remains a file in the CWD or path??? // OperationResult = (BOOLEAN)(ShellIsFileInPath(StatementWalker)==EFI_SUCCESS); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"available"); Status = EFI_INVALID_PARAMETER; } } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"profile")) { if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && StatementWalker[StrLen(StatementWalker)-1] == L')') { // // Chop off that ')' // StatementWalker[StrLen(StatementWalker)-1] = CHAR_NULL; OperationResult = IsValidProfile(StatementWalker); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"profile"); Status = EFI_INVALID_PARAMETER; } } else if (StartParameterNumber+1 >= EndParameterNumber) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[StartParameterNumber]); Status = EFI_INVALID_PARAMETER; } else { // // must be 'item binop item' style // Compare1 = NULL; Compare2 = NULL; BinOp = OperatorMax; // // get the first item // StatementWalker = gEfiShellParametersProtocol->Argv[StartParameterNumber]; if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"efierror")) { TempSpot = StrStr(StatementWalker, L")"); if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && TempSpot != NULL) { *TempSpot = CHAR_NULL; if (ShellIsHexOrDecimalNumber(StatementWalker, FALSE, FALSE)) { UnicodeSPrint(HexString, sizeof(HexString), L"0x%x", ShellStrToUintn(StatementWalker)|MAX_BIT); ASSERT(Compare1 == NULL); Compare1 = StrnCatGrow(&Compare1, NULL, HexString, 0); StatementWalker += StrLen(StatementWalker) + 1; } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror"); Status = EFI_INVALID_PARAMETER; } } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"efierror"); Status = EFI_INVALID_PARAMETER; } } else if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"pierror")) { TempSpot = StrStr(StatementWalker, L")"); if (IsNextFragment((CONST CHAR16**)(&StatementWalker), L"(") && TempSpot != NULL) { *TempSpot = CHAR_NULL; if (ShellIsHexOrDecimalNumber(StatementWalker, FALSE, FALSE)) { UnicodeSPrint(HexString, sizeof(HexString), L"0x%x", ShellStrToUintn(StatementWalker)|MAX_BIT|(MAX_BIT>>2)); ASSERT(Compare1 == NULL); Compare1 = StrnCatGrow(&Compare1, NULL, HexString, 0); StatementWalker += StrLen(StatementWalker) + 1; } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SYNTAX_IN), gShellLevel1HiiHandle, L"pierror"); Status = EFI_INVALID_PARAMETER; } } else {
/** Function for 'for' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunFor ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; SHELL_STATUS ShellStatus; SCRIPT_FILE *CurrentScriptFile; CHAR16 *ArgSet; CHAR16 *ArgSetWalker; UINTN ArgSize; UINTN LoopVar; SHELL_FOR_INFO *Info; CHAR16 *TempString; CHAR16 *TempSpot; BOOLEAN FirstPass; EFI_SHELL_FILE_INFO *Node; EFI_SHELL_FILE_INFO *FileList; UINTN NewSize; ArgSet = NULL; ArgSize = 0; ShellStatus = SHELL_SUCCESS; ArgSetWalker = NULL; TempString = NULL; FirstPass = FALSE; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); Status = CommandInit(); ASSERT_EFI_ERROR(Status); if (!gEfiShellProtocol->BatchIsActive()) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"For"); return (SHELL_UNSUPPORTED); } if (gEfiShellParametersProtocol->Argc < 4) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel1HiiHandle); return (SHELL_INVALID_PARAMETER); } CurrentScriptFile = ShellCommandGetCurrentScriptFile(); ASSERT(CurrentScriptFile != NULL); if (CurrentScriptFile->CurrentCommand->Data == NULL) { FirstPass = TRUE; // // Make sure that an End exists. // if (!MoveToTag(GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, TRUE, FALSE)) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EndFor", L"For", CurrentScriptFile->CurrentCommand!=NULL ?CurrentScriptFile->CurrentCommand->Line:0); return (SHELL_DEVICE_ERROR); } // // Process the line. // if (gEfiShellParametersProtocol->Argv[1][0] != L'%' || gEfiShellParametersProtocol->Argv[1][2] != CHAR_NULL ||!((gEfiShellParametersProtocol->Argv[1][1] >= L'a' && gEfiShellParametersProtocol->Argv[1][1] <= L'z') ||(gEfiShellParametersProtocol->Argv[1][1] >= L'A' && gEfiShellParametersProtocol->Argv[1][1] <= L'Z')) ) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_VAR), gShellLevel1HiiHandle, gEfiShellParametersProtocol->Argv[1]); return (SHELL_INVALID_PARAMETER); } if (gUnicodeCollation->StriColl( gUnicodeCollation, L"in", gEfiShellParametersProtocol->Argv[2]) == 0) { for (LoopVar = 0x3 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) { ASSERT((ArgSet == NULL && ArgSize == 0) || (ArgSet != NULL)); if (StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"*") != NULL ||StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"?") != NULL ||StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"[") != NULL ||StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"]") != NULL) { FileList = NULL; Status = ShellOpenFileMetaArg ((CHAR16*)gEfiShellParametersProtocol->Argv[LoopVar], EFI_FILE_MODE_READ, &FileList); if (EFI_ERROR(Status) || FileList == NULL || IsListEmpty(&FileList->Link)) { ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" \"", 0); ArgSet = StrnCatGrow(&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0); ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0); } else { for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link) ; !IsNull(&FileList->Link, &Node->Link) ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link) ){ ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" \"", 0); ArgSet = StrnCatGrow(&ArgSet, &ArgSize, Node->FullName, 0); ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0); } ShellCloseFileMetaArg(&FileList); } } else { ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" \"", 0); ArgSet = StrnCatGrow(&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0); ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0); } } if (ArgSet == NULL) { ShellStatus = SHELL_OUT_OF_RESOURCES; } else { // // set up for an 'in' for loop // NewSize = StrSize(ArgSet); NewSize += sizeof(SHELL_FOR_INFO)+StrSize(gEfiShellParametersProtocol->Argv[1]); Info = AllocateZeroPool(NewSize); ASSERT(Info != NULL); Info->Signature = SHELL_FOR_INFO_SIGNATURE; CopyMem(Info->Set, ArgSet, StrSize(ArgSet)); NewSize = StrSize(gEfiShellParametersProtocol->Argv[1]); CopyMem(Info->Set+(StrSize(ArgSet)/sizeof(Info->Set[0])), gEfiShellParametersProtocol->Argv[1], NewSize); Info->ReplacementName = Info->Set+StrSize(ArgSet)/sizeof(Info->Set[0]); Info->CurrentValue = (CHAR16*)Info->Set; Info->Step = 0; Info->Current = 0; Info->End = 0; if (InternalIsAliasOnList(Info->ReplacementName, &CurrentScriptFile->SubstList)) { Info->RemoveSubstAlias = FALSE; } else { Info->RemoveSubstAlias = TRUE; } CurrentScriptFile->CurrentCommand->Data = Info; } } else if (gUnicodeCollation->StriColl( gUnicodeCollation, L"run", gEfiShellParametersProtocol->Argv[2]) == 0) { for (LoopVar = 0x3 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) { ASSERT((ArgSet == NULL && ArgSize == 0) || (ArgSet != NULL)); if (ArgSet == NULL) { // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0); } else { ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0); } ArgSet = StrnCatGrow(&ArgSet, &ArgSize, gEfiShellParametersProtocol->Argv[LoopVar], 0); // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" ", 0); } if (ArgSet == NULL) { ShellStatus = SHELL_OUT_OF_RESOURCES; } else { // // set up for a 'run' for loop // Info = AllocateZeroPool(sizeof(SHELL_FOR_INFO)+StrSize(gEfiShellParametersProtocol->Argv[1])); ASSERT(Info != NULL); Info->Signature = SHELL_FOR_INFO_SIGNATURE; CopyMem(Info->Set, gEfiShellParametersProtocol->Argv[1], StrSize(gEfiShellParametersProtocol->Argv[1])); Info->ReplacementName = Info->Set; Info->CurrentValue = NULL; ArgSetWalker = ArgSet; if (ArgSetWalker[0] != L'(') { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, CurrentScriptFile!=NULL && CurrentScriptFile->CurrentCommand!=NULL ? CurrentScriptFile->CurrentCommand->Line:0); ShellStatus = SHELL_INVALID_PARAMETER; } else { TempSpot = StrStr(ArgSetWalker, L")"); if (TempSpot != NULL) { TempString = TempSpot+1; if (*(TempString) != CHAR_NULL) { while(TempString != NULL && *TempString == L' ') { TempString++; } if (StrLen(TempString) > 0) { TempSpot = NULL; } } } if (TempSpot == NULL) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, CurrentScriptFile!=NULL && CurrentScriptFile->CurrentCommand!=NULL ? CurrentScriptFile->CurrentCommand->Line:0); ShellStatus = SHELL_INVALID_PARAMETER; } else { *TempSpot = CHAR_NULL; ArgSetWalker++; while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') { ArgSetWalker++; } if (!ShellIsValidForNumber(ArgSetWalker)) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, CurrentScriptFile!=NULL && CurrentScriptFile->CurrentCommand!=NULL ? CurrentScriptFile->CurrentCommand->Line:0); ShellStatus = SHELL_INVALID_PARAMETER; } else { if (ArgSetWalker[0] == L'-') { Info->Current = 0 - (INTN)ReturnUintn(ArgSetWalker+1); } else { Info->Current = (INTN)ReturnUintn(ArgSetWalker); } ArgSetWalker = StrStr(ArgSetWalker, L" "); while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') { ArgSetWalker++; } if (ArgSetWalker == NULL || *ArgSetWalker == CHAR_NULL || !ShellIsValidForNumber(ArgSetWalker)){ ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, CurrentScriptFile!=NULL && CurrentScriptFile->CurrentCommand!=NULL ? CurrentScriptFile->CurrentCommand->Line:0); ShellStatus = SHELL_INVALID_PARAMETER; } else { if (ArgSetWalker[0] == L'-') { Info->End = 0 - (INTN)ReturnUintn(ArgSetWalker+1); } else { Info->End = (INTN)ReturnUintn(ArgSetWalker); } if (Info->Current < Info->End) { Info->Step = 1; } else { Info->Step = -1; } ArgSetWalker = StrStr(ArgSetWalker, L" "); while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') { ArgSetWalker++; } if (ArgSetWalker != NULL && *ArgSetWalker != CHAR_NULL) { if (ArgSetWalker == NULL || *ArgSetWalker == CHAR_NULL || !ShellIsValidForNumber(ArgSetWalker)){ ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, CurrentScriptFile!=NULL && CurrentScriptFile->CurrentCommand!=NULL ? CurrentScriptFile->CurrentCommand->Line:0); ShellStatus = SHELL_INVALID_PARAMETER; } else { if (*ArgSetWalker == L')') { ASSERT(Info->Step == 1 || Info->Step == -1); } else { if (ArgSetWalker[0] == L'-') { Info->Step = 0 - (INTN)ReturnUintn(ArgSetWalker+1); } else { Info->Step = (INTN)ReturnUintn(ArgSetWalker); } if (StrStr(ArgSetWalker, L" ") != NULL) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, CurrentScriptFile!=NULL && CurrentScriptFile->CurrentCommand!=NULL ? CurrentScriptFile->CurrentCommand->Line:0); ShellStatus = SHELL_INVALID_PARAMETER; } } } } } } } } if (ShellStatus == SHELL_SUCCESS) { if (InternalIsAliasOnList(Info->ReplacementName, &CurrentScriptFile->SubstList)) { Info->RemoveSubstAlias = FALSE; } else { Info->RemoveSubstAlias = TRUE; } } if (CurrentScriptFile->CurrentCommand != NULL) { CurrentScriptFile->CurrentCommand->Data = Info; } } } else { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_SCRIPT), gShellLevel1HiiHandle, ArgSet, CurrentScriptFile!=NULL && CurrentScriptFile->CurrentCommand!=NULL ? CurrentScriptFile->CurrentCommand->Line:0); ShellStatus = SHELL_INVALID_PARAMETER; } } else { // // These need to be NULL since they are used to determine if this is the first pass later on... // ASSERT(ArgSetWalker == NULL); ASSERT(ArgSet == NULL); } if (CurrentScriptFile != NULL && CurrentScriptFile->CurrentCommand != NULL) { Info = (SHELL_FOR_INFO*)CurrentScriptFile->CurrentCommand->Data; if (CurrentScriptFile->CurrentCommand->Reset) { Info->CurrentValue = (CHAR16*)Info->Set; FirstPass = TRUE; CurrentScriptFile->CurrentCommand->Reset = FALSE; } } else { ShellStatus = SHELL_UNSUPPORTED; Info = NULL; } if (ShellStatus == SHELL_SUCCESS) { ASSERT(Info != NULL); if (Info->Step != 0) { // // only advance if not the first pass // if (!FirstPass) { // // sequence version of for loop... // Info->Current += Info->Step; } TempString = AllocateZeroPool(50*sizeof(CHAR16)); UnicodeSPrint(TempString, 50*sizeof(CHAR16), L"%d", Info->Current); InternalUpdateAliasOnList(Info->ReplacementName, TempString, &CurrentScriptFile->SubstList); FreePool(TempString); if ((Info->Step > 0 && Info->Current > Info->End) || (Info->Step < 0 && Info->Current < Info->End)) { CurrentScriptFile->CurrentCommand->Data = NULL; // // find the matching endfor (we're done with the loop) // if (!MoveToTag(GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, FALSE, FALSE)) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EndFor", L"For", CurrentScriptFile!=NULL && CurrentScriptFile->CurrentCommand!=NULL ? CurrentScriptFile->CurrentCommand->Line:0); ShellStatus = SHELL_DEVICE_ERROR; } if (Info->RemoveSubstAlias) { // // remove item from list // InternalRemoveAliasFromList(Info->ReplacementName, &CurrentScriptFile->SubstList); } FreePool(Info); } } else { // // Must be in 'in' version of for loop... // ASSERT(Info->Set != NULL); if (Info->CurrentValue != NULL && *Info->CurrentValue != CHAR_NULL) { if (Info->CurrentValue[0] == L' ') { Info->CurrentValue++; } if (Info->CurrentValue[0] == L'\"') { Info->CurrentValue++; } // // do the next one of the set // ASSERT(TempString == NULL); TempString = StrnCatGrow(&TempString, NULL, Info->CurrentValue, 0); if (TempString == NULL) { ShellStatus = SHELL_OUT_OF_RESOURCES; } else { TempSpot = StrStr(TempString, L"\" \""); if (TempSpot != NULL) { *TempSpot = CHAR_NULL; } while (TempString[StrLen(TempString)-1] == L'\"') { TempString[StrLen(TempString)-1] = CHAR_NULL; } InternalUpdateAliasOnList(Info->ReplacementName, TempString, &CurrentScriptFile->SubstList); Info->CurrentValue += StrLen(TempString); if (Info->CurrentValue[0] == L'\"') { Info->CurrentValue++; } while (Info->CurrentValue[0] == L' ') { Info->CurrentValue++; } if (Info->CurrentValue[0] == L'\"') { Info->CurrentValue++; } FreePool(TempString); } } else { CurrentScriptFile->CurrentCommand->Data = NULL; // // find the matching endfor (we're done with the loop) // if (!MoveToTag(GetNextNode, L"endfor", L"for", NULL, CurrentScriptFile, TRUE, FALSE, FALSE)) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, L"EndFor", L"For", CurrentScriptFile!=NULL && CurrentScriptFile->CurrentCommand!=NULL ? CurrentScriptFile->CurrentCommand->Line:0); ShellStatus = SHELL_DEVICE_ERROR; } if (Info->RemoveSubstAlias) { // // remove item from list // InternalRemoveAliasFromList(Info->ReplacementName, &CurrentScriptFile->SubstList); } FreePool(Info); } } } if (ArgSet != NULL) { FreePool(ArgSet); } return (ShellStatus); }
/** Verify that the DateString is valid and if so set that as the current date. @param[in] DateString The pointer to a string representation of the date. @retval SHELL_INVALID_PARAMETER DateString was NULL. @retval SHELL_INVALID_PARAMETER DateString was mis-formatted. @retval SHELL_SUCCESS The operation was successful. **/ SHELL_STATUS EFIAPI CheckAndSetDate ( IN CONST CHAR16 *DateString ) { EFI_TIME TheTime; EFI_STATUS Status; CHAR16 *DateStringCopy; CHAR16 *Walker; CHAR16 *Walker1; if (!InternalIsTimeLikeString(DateString, L'/', 2, 2, FALSE)) { return (SHELL_INVALID_PARAMETER); } Status = gRT->GetTime(&TheTime, NULL); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"gRT->GetTime", Status); return (SHELL_DEVICE_ERROR); } DateStringCopy = NULL; DateStringCopy = StrnCatGrow(&DateStringCopy, NULL, DateString, 0); if (DateStringCopy == NULL) { return (SHELL_OUT_OF_RESOURCES); } Walker = DateStringCopy; TheTime.Month = 0xFF; TheTime.Day = 0xFF; TheTime.Year = 0xFFFF; Walker1 = StrStr(Walker, L"/"); if (Walker1 != NULL && *Walker1 == L'/') { *Walker1 = CHAR_NULL; } TheTime.Month = (UINT8)ShellStrToUintn (Walker); if (Walker1 != NULL) { Walker = Walker1 + 1; } Walker1 = Walker!=NULL?StrStr(Walker, L"/"):NULL; if (Walker1 != NULL && *Walker1 == L'/') { *Walker1 = CHAR_NULL; } if (Walker != NULL && Walker[0] != CHAR_NULL) { TheTime.Day = (UINT8)ShellStrToUintn (Walker); if (Walker1 != NULL) { Walker = Walker1 + 1; } Walker1 = Walker!=NULL?StrStr(Walker, L"/"):NULL; if (Walker1 != NULL && *Walker1 == L'/') { *Walker1 = CHAR_NULL; } if (Walker != NULL && Walker[0] != CHAR_NULL) { TheTime.Year = (UINT16)ShellStrToUintn (Walker); } } if (TheTime.Year < 100) { if (TheTime.Year >= 98) { TheTime.Year = (UINT16)(1900 + TheTime.Year); } else { TheTime.Year = (UINT16)(2000 + TheTime.Year); } } Status = gRT->SetTime(&TheTime); if (!EFI_ERROR(Status)){ return (SHELL_SUCCESS); } return (SHELL_INVALID_PARAMETER); }
/** Verify that the TimeString is valid and if so set that as the current time. @param[in] TimeString The pointer to a string representation of the time. @param[in] Tz The value to set for TimeZone. @param[in] Daylight The value to set for Daylight. @retval SHELL_INVALID_PARAMETER TimeString was NULL. @retval SHELL_INVALID_PARAMETER TimeString was mis-formatted. @retval SHELL_SUCCESS The operation was successful. **/ SHELL_STATUS EFIAPI CheckAndSetTime ( IN CONST CHAR16 *TimeString, IN CONST INT16 Tz, IN CONST UINT8 Daylight ) { EFI_TIME TheTime; EFI_STATUS Status; CHAR16 *TimeStringCopy; CHAR16 *Walker1; CHAR16 *Walker2; if (TimeString != NULL && !InternalIsTimeLikeString(TimeString, L':', 1, 2, FALSE)) { return (SHELL_INVALID_PARAMETER); } if (Daylight != 0xFF &&((Daylight & (EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT)) != Daylight)) { return (SHELL_INVALID_PARAMETER); } Status = gRT->GetTime(&TheTime, NULL); ASSERT_EFI_ERROR(Status); if (TimeString != NULL) { TimeStringCopy = NULL; TimeStringCopy = StrnCatGrow(&TimeStringCopy, NULL, TimeString, 0); Walker1 = TimeStringCopy; TheTime.Hour = 0xFF; TheTime.Minute = 0xFF; Walker2 = Walker1!=NULL?StrStr(Walker1, L":"):NULL; if (Walker2 != NULL && *Walker2 == L':') { *Walker2 = CHAR_NULL; } TheTime.Hour = (UINT8)ShellStrToUintn (Walker1); if (Walker2 != NULL) { Walker1 = Walker2 + 1; } Walker2 = Walker1!=NULL?StrStr(Walker1, L":"):NULL; if (Walker2 != NULL && *Walker2 == L':') { *Walker2 = CHAR_NULL; } if (Walker1 != NULL && Walker1[0] != CHAR_NULL) { TheTime.Minute = (UINT8)ShellStrToUintn (Walker1); if (Walker2 != NULL) { Walker1 = Walker2 + 1; } if (Walker1 != NULL && Walker1[0] != CHAR_NULL) { TheTime.Second = (UINT8)ShellStrToUintn (Walker1); } } SHELL_FREE_NON_NULL(TimeStringCopy); } if ((Tz >= -1440 && Tz <= 1440)||(Tz == 0x7FF)) { TheTime.TimeZone = Tz; } if (Daylight != 0xFF) { TheTime.Daylight = Daylight; } Status = gRT->SetTime(&TheTime); if (!EFI_ERROR(Status)){ return (SHELL_SUCCESS); } return (SHELL_INVALID_PARAMETER); }
/** Function for 'goto' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunGoto ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; CHAR16 *CompareString; UINTN Size; SCRIPT_FILE *CurrentScriptFile; ShellStatus = SHELL_SUCCESS; CompareString = NULL; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); Status = CommandInit(); ASSERT_EFI_ERROR(Status); if (!gEfiShellProtocol->BatchIsActive()) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_NO_SCRIPT), gShellLevel1HiiHandle, L"Goto"); return (SHELL_UNSUPPORTED); } // // parse the command line // Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel1HiiHandle, L"goto", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { if (ShellCommandLineGetRawValue(Package, 2) != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel1HiiHandle, L"goto"); ShellStatus = SHELL_INVALID_PARAMETER; } else if (ShellCommandLineGetRawValue(Package, 1) == NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel1HiiHandle, L"goto"); ShellStatus = SHELL_INVALID_PARAMETER; } else { Size = 0; ASSERT((CompareString == NULL && Size == 0) || (CompareString != NULL)); CompareString = StrnCatGrow(&CompareString, &Size, L":", 0); CompareString = StrnCatGrow(&CompareString, &Size, ShellCommandLineGetRawValue(Package, 1), 0); // // Check forwards and then backwards for a label... // if (!MoveToTag(GetNextNode, L"endfor", L"for", CompareString, ShellCommandGetCurrentScriptFile(), FALSE, FALSE, TRUE)) { CurrentScriptFile = ShellCommandGetCurrentScriptFile(); ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_SYNTAX_NO_MATCHING), gShellLevel1HiiHandle, CompareString, L"Goto", CurrentScriptFile!=NULL && CurrentScriptFile->CurrentCommand!=NULL ? CurrentScriptFile->CurrentCommand->Line:0); ShellStatus = SHELL_NOT_FOUND; } FreePool(CompareString); } ShellCommandLineFreeVarList (Package); } return (ShellStatus); }
/** Function for 'help' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunHelp ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; CONST COMMAND_LIST *CommandList; CONST COMMAND_LIST *Node; CHAR16 *CommandToGetHelpOn; CHAR16 *SectionToGetHelpOn; CHAR16 *HiiString; BOOLEAN Found; BOOLEAN PrintCommandText; PrintCommandText = TRUE; ProblemParam = NULL; ShellStatus = SHELL_SUCCESS; CommandToGetHelpOn = NULL; SectionToGetHelpOn = NULL; Found = FALSE; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); Status = CommandInit(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel3HiiHandle, L"help", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { // // Check for conflicting parameters. // if (ShellCommandLineGetFlag(Package, L"-usage") &&ShellCommandLineGetFlag(Package, L"-section") &&(ShellCommandLineGetFlag(Package, L"-verbose") || ShellCommandLineGetFlag(Package, L"-v")) ){ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel3HiiHandle, L"help"); ShellStatus = SHELL_INVALID_PARAMETER; } else if (ShellCommandLineGetRawValue(Package, 2) != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel3HiiHandle, L"help"); ShellStatus = SHELL_INVALID_PARAMETER; } else { // // Get the command name we are getting help on // ASSERT(CommandToGetHelpOn == NULL); StrnCatGrow(&CommandToGetHelpOn, NULL, ShellCommandLineGetRawValue(Package, 1), 0); if (CommandToGetHelpOn == NULL && ShellCommandLineGetFlag(Package, L"-?")) { // // If we dont have a command and we got a simple -? // we are looking for help on help command. // StrnCatGrow(&CommandToGetHelpOn, NULL, L"help", 0); } if (CommandToGetHelpOn == NULL) { StrnCatGrow(&CommandToGetHelpOn, NULL, L"*", 0); ASSERT(SectionToGetHelpOn == NULL); StrnCatGrow(&SectionToGetHelpOn, NULL, L"NAME", 0); } else { PrintCommandText = FALSE; ASSERT(SectionToGetHelpOn == NULL); // // Get the section name for the given command name // if (ShellCommandLineGetFlag(Package, L"-section")) { StrnCatGrow(&SectionToGetHelpOn, NULL, ShellCommandLineGetValue(Package, L"-section"), 0); } else if (ShellCommandLineGetFlag(Package, L"-usage")) { StrnCatGrow(&SectionToGetHelpOn, NULL, L"NAME,SYNOPSIS", 0); } else if (ShellCommandLineGetFlag(Package, L"-verbose") || ShellCommandLineGetFlag(Package, L"-v")) { } else { // // The output of help <command> will display NAME, SYNOPSIS, OPTIONS, DESCRIPTION, and EXAMPLES sections. // StrnCatGrow (&SectionToGetHelpOn, NULL, L"NAME,SYNOPSIS,OPTIONS,DESCRIPTION,EXAMPLES", 0); } } if (gUnicodeCollation->StriColl(gUnicodeCollation, CommandToGetHelpOn, L"special") == 0) { // // we need info on the special characters // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_SC_HEADER), gShellLevel3HiiHandle); HiiString = HiiGetString(gShellLevel3HiiHandle, STRING_TOKEN(STR_HELP_SC_DATA), NULL); ShellPrintEx(-1, -1, L"%s", HiiString); FreePool(HiiString); Found = TRUE; } else { CommandList = ShellCommandGetCommandList(TRUE); ASSERT(CommandList != NULL); for ( Node = (COMMAND_LIST*)GetFirstNode(&CommandList->Link) ; CommandList != NULL && !IsListEmpty(&CommandList->Link) && !IsNull(&CommandList->Link, &Node->Link) ; Node = (COMMAND_LIST*)GetNextNode(&CommandList->Link, &Node->Link) ){ // // Checking execution break flag when print multiple command help information. // if (ShellGetExecutionBreakFlag ()) { break; } if ((gUnicodeCollation->MetaiMatch(gUnicodeCollation, Node->CommandString, CommandToGetHelpOn)) || (gEfiShellProtocol->GetAlias(CommandToGetHelpOn, NULL) != NULL && (gUnicodeCollation->MetaiMatch(gUnicodeCollation, Node->CommandString, (CHAR16*)(gEfiShellProtocol->GetAlias(CommandToGetHelpOn, NULL)))))) { // // We have a command to look for help on. // Status = ShellPrintHelp(Node->CommandString, SectionToGetHelpOn, PrintCommandText); if (Status == EFI_DEVICE_ERROR) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_INV), gShellLevel3HiiHandle, Node->CommandString); } else if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_NF), gShellLevel3HiiHandle, Node->CommandString); } else { Found = TRUE; } } } // // now try to match against the dynamic command list and print help // Status = PrintDynamicCommandHelp (CommandToGetHelpOn, SectionToGetHelpOn, PrintCommandText); if (!EFI_ERROR(Status)) { Found = TRUE; } // // Search the .man file for Shell applications (Shell external commands). // if (!Found) { Status = ShellPrintHelp(CommandToGetHelpOn, SectionToGetHelpOn, FALSE); if (Status == EFI_DEVICE_ERROR) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_INV), gShellLevel3HiiHandle, CommandToGetHelpOn); } else if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_NF), gShellLevel3HiiHandle, CommandToGetHelpOn); } else { Found = TRUE; } } } if (!Found) { ShellStatus = SHELL_NOT_FOUND; } // // free the command line package // ShellCommandLineFreeVarList (Package); } } if (CommandToGetHelpOn != NULL && StrCmp(CommandToGetHelpOn, L"*") == 0){ // // If '*' then the command entered was 'Help' without qualifiers, This footer // provides additional info on help switches // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_FOOTER), gShellLevel3HiiHandle); } if (CommandToGetHelpOn != NULL) { FreePool(CommandToGetHelpOn); } if (SectionToGetHelpOn != NULL) { FreePool(SectionToGetHelpOn); } return (ShellStatus); }
/** Verify that the TimeZoneString is valid and if so set that as the current timezone. @param[in] TimeZoneString The pointer to a string representation of the timezone. @retval SHELL_INVALID_PARAMETER TimeZoneString was NULL. @retval SHELL_INVALID_PARAMETER TimeZoneString was mis-formatted. @retval SHELL_SUCCESS The operation was successful. **/ SHELL_STATUS EFIAPI CheckAndSetTimeZone ( IN CONST CHAR16 *TimeZoneString ) { EFI_TIME TheTime; EFI_STATUS Status; CHAR16 *TimeZoneCopy; CHAR16 *Walker; CHAR16 *Walker2; UINTN LoopVar; if (TimeZoneString == NULL) { return (SHELL_INVALID_PARAMETER); } if (TimeZoneString != NULL && !InternalIsTimeLikeString(TimeZoneString, L':', 1, 1, TRUE)) { return (SHELL_INVALID_PARAMETER); } Status = gRT->GetTime(&TheTime, NULL); if (EFI_ERROR(Status)) { return (SHELL_DEVICE_ERROR); } TimeZoneCopy = NULL; TimeZoneCopy = StrnCatGrow(&TimeZoneCopy, NULL, TimeZoneString, 0); if (TimeZoneCopy == NULL) { return (SHELL_OUT_OF_RESOURCES); } Walker = TimeZoneCopy; Walker2 = StrStr(Walker, L":"); if (Walker2 != NULL && *Walker2 == L':') { *Walker2 = CHAR_NULL; } if (*Walker == L'-') { TheTime.TimeZone = (INT16)((ShellStrToUintn (++Walker)) * 60); } else { TheTime.TimeZone = (INT16)((ShellStrToUintn (Walker)) * -60); } if (Walker2 != NULL) { Walker = Walker2 + 1; } if (Walker != NULL && Walker[0] != CHAR_NULL) { if (TheTime.TimeZone < 0) { TheTime.TimeZone = (INT16)(TheTime.TimeZone - (UINT8)ShellStrToUintn (Walker)); } else { TheTime.TimeZone = (INT16)(TheTime.TimeZone + (UINT8)ShellStrToUintn (Walker)); } } Status = EFI_INVALID_PARAMETER; for ( LoopVar = 0 ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0]) ; LoopVar++ ){ if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) { Status = gRT->SetTime(&TheTime); break; } } FreePool(TimeZoneCopy); if (!EFI_ERROR(Status)){ return (SHELL_SUCCESS); } return (SHELL_INVALID_PARAMETER); }
/** Convert a string representation of a guid to a Guid value. @param[in] StringGuid The pointer to the string of a guid. @param[in, out] Guid The pointer to the GUID structure to populate. @retval EFI_INVALID_PARAMETER A parameter was invalid. @retval EFI_SUCCESS The conversion was successful. **/ EFI_STATUS EFIAPI ConvertStringToGuid ( IN CONST CHAR16 *StringGuid, IN OUT EFI_GUID *Guid ) { CHAR16 *TempCopy; CHAR16 *TempSpot; CHAR16 *Walker; UINT64 TempVal; EFI_STATUS Status; if (StringGuid == NULL) { return (EFI_INVALID_PARAMETER); } else if (StrLen(StringGuid) != 36) { return (EFI_INVALID_PARAMETER); } TempCopy = NULL; TempCopy = StrnCatGrow(&TempCopy, NULL, StringGuid, 0); if (TempCopy == NULL) { return (EFI_OUT_OF_RESOURCES); } Walker = TempCopy; TempSpot = StrStr(Walker, L"-"); if (TempSpot != NULL) { *TempSpot = CHAR_NULL; } Status = ShellConvertStringToUint64(Walker, &TempVal, TRUE, FALSE); if (EFI_ERROR(Status)) { FreePool(TempCopy); return (Status); } Guid->Data1 = (UINT32)TempVal; Walker += 9; TempSpot = StrStr(Walker, L"-"); if (TempSpot != NULL) { *TempSpot = CHAR_NULL; } Status = ShellConvertStringToUint64(Walker, &TempVal, TRUE, FALSE); if (EFI_ERROR(Status)) { FreePool(TempCopy); return (Status); } Guid->Data2 = (UINT16)TempVal; Walker += 5; TempSpot = StrStr(Walker, L"-"); if (TempSpot != NULL) { *TempSpot = CHAR_NULL; } Status = ShellConvertStringToUint64(Walker, &TempVal, TRUE, FALSE); if (EFI_ERROR(Status)) { FreePool(TempCopy); return (Status); } Guid->Data3 = (UINT16)TempVal; Walker += 5; Guid->Data4[0] = (UINT8)(HexCharToUintn(Walker[0]) * 16); Guid->Data4[0] = (UINT8)(Guid->Data4[0]+ (UINT8)HexCharToUintn(Walker[1])); Walker += 2; Guid->Data4[1] = (UINT8)(HexCharToUintn(Walker[0]) * 16); Guid->Data4[1] = (UINT8)(Guid->Data4[1] + (UINT8)HexCharToUintn(Walker[1])); Walker += 3; Guid->Data4[2] = (UINT8)(HexCharToUintn(Walker[0]) * 16); Guid->Data4[2] = (UINT8)(Guid->Data4[2] + (UINT8)HexCharToUintn(Walker[1])); Walker += 2; Guid->Data4[3] = (UINT8)(HexCharToUintn(Walker[0]) * 16); Guid->Data4[3] = (UINT8)(Guid->Data4[3] + (UINT8)HexCharToUintn(Walker[1])); Walker += 2; Guid->Data4[4] = (UINT8)(HexCharToUintn(Walker[0]) * 16); Guid->Data4[4] = (UINT8)(Guid->Data4[4] + (UINT8)HexCharToUintn(Walker[1])); Walker += 2; Guid->Data4[5] = (UINT8)(HexCharToUintn(Walker[0]) * 16); Guid->Data4[5] = (UINT8)(Guid->Data4[5] + (UINT8)HexCharToUintn(Walker[1])); Walker += 2; Guid->Data4[6] = (UINT8)(HexCharToUintn(Walker[0]) * 16); Guid->Data4[6] = (UINT8)(Guid->Data4[6] + (UINT8)HexCharToUintn(Walker[1])); Walker += 2; Guid->Data4[7] = (UINT8)(HexCharToUintn(Walker[0]) * 16); Guid->Data4[7] = (UINT8)(Guid->Data4[7] + (UINT8)HexCharToUintn(Walker[1])); FreePool(TempCopy); return (EFI_SUCCESS); }
/** Function to Copy one file to another location If the destination exists the user will be prompted and the result put into *resp @param[in] Source pointer to source file name @param[in] Dest pointer to destination file name @param[out] Resp pointer to response from question. Pass back on looped calling @param[in] SilentMode whether to run in quiet mode or not @retval SHELL_SUCCESS The source file was copied to the destination **/ SHELL_STATUS EFIAPI CopySingleFile( IN CONST CHAR16 *Source, IN CONST CHAR16 *Dest, OUT VOID **Resp, IN BOOLEAN SilentMode ) { VOID *Response; UINTN ReadSize; SHELL_FILE_HANDLE SourceHandle; SHELL_FILE_HANDLE DestHandle; EFI_STATUS Status; VOID *Buffer; CHAR16 *TempName; UINTN Size; EFI_SHELL_FILE_INFO *List; SHELL_STATUS ShellStatus; UINT64 SourceFileSize; UINT64 DestFileSize; EFI_FILE_PROTOCOL *DestVolumeFP; EFI_FILE_SYSTEM_INFO *DestVolumeInfo; UINTN DestVolumeInfoSize; ASSERT(Resp != NULL); SourceHandle = NULL; DestHandle = NULL; Response = *Resp; List = NULL; DestVolumeInfo = NULL; ReadSize = PcdGet16(PcdShellFileOperationSize); // Why bother copying a file to itself if (StrCmp(Source, Dest) == 0) { return (SHELL_SUCCESS); } // // Open destination file without create // Status = ShellOpenFileByName(Dest, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0); // // close file // if (DestHandle != NULL) { ShellCloseFile(&DestHandle); DestHandle = NULL; } // // if the destination file existed check response and possibly prompt user // if (!EFI_ERROR(Status)) { if (Response == NULL && !SilentMode) { Status = ShellPromptForResponseHii(ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response); } // // possibly return based on response // if (!SilentMode) { switch (*(SHELL_PROMPT_RESPONSE*)Response) { case ShellPromptResponseNo: // // return success here so we dont stop the process // return (SHELL_SUCCESS); case ShellPromptResponseCancel: *Resp = Response; // // indicate to stop everything // return (SHELL_ABORTED); case ShellPromptResponseAll: *Resp = Response; case ShellPromptResponseYes: break; default: return SHELL_ABORTED; } } } if (ShellIsDirectory(Source) == EFI_SUCCESS) { Status = ShellCreateDirectory(Dest, &DestHandle); if (EFI_ERROR(Status)) { return (SHELL_ACCESS_DENIED); } // // Now copy all the files under the directory... // TempName = NULL; Size = 0; StrnCatGrow(&TempName, &Size, Source, 0); StrnCatGrow(&TempName, &Size, L"\\*", 0); if (TempName != NULL) { ShellOpenFileMetaArg((CHAR16*)TempName, EFI_FILE_MODE_READ, &List); *TempName = CHAR_NULL; StrnCatGrow(&TempName, &Size, Dest, 0); StrnCatGrow(&TempName, &Size, L"\\", 0); ShellStatus = ValidateAndCopyFiles(List, TempName, SilentMode, TRUE, Resp); ShellCloseFileMetaArg(&List); SHELL_FREE_NON_NULL(TempName); Size = 0; } } else { // // open file with create enabled // Status = ShellOpenFileByName(Dest, &DestHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); if (EFI_ERROR(Status)) { return (SHELL_ACCESS_DENIED); } // // open source file // Status = ShellOpenFileByName(Source, &SourceHandle, EFI_FILE_MODE_READ, 0); ASSERT_EFI_ERROR(Status); // //get file size of source file and freespace available on destination volume // ShellGetFileSize(SourceHandle, &SourceFileSize); ShellGetFileSize(DestHandle, &DestFileSize); // //if the destination file already exists then it will be replaced, meaning the sourcefile effectively needs less storage space // if(DestFileSize < SourceFileSize){ SourceFileSize -= DestFileSize; } else { SourceFileSize = 0; } // //get the system volume info to check the free space // DestVolumeFP = ConvertShellHandleToEfiFileProtocol(DestHandle); DestVolumeInfo = NULL; DestVolumeInfoSize = 0; Status = DestVolumeFP->GetInfo( DestVolumeFP, &gEfiFileSystemInfoGuid, &DestVolumeInfoSize, DestVolumeInfo ); if (Status == EFI_BUFFER_TOO_SMALL) { DestVolumeInfo = AllocateZeroPool(DestVolumeInfoSize); Status = DestVolumeFP->GetInfo( DestVolumeFP, &gEfiFileSystemInfoGuid, &DestVolumeInfoSize, DestVolumeInfo ); } // //check if enough space available on destination drive to complete copy // if (DestVolumeInfo->FreeSpace < SourceFileSize) { // //not enough space on destination directory to copy file // SHELL_FREE_NON_NULL(DestVolumeInfo); ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CPY_FAIL), gShellLevel2HiiHandle); return(SHELL_VOLUME_FULL); } else { // // copy data between files // Buffer = AllocateZeroPool(ReadSize); ASSERT(Buffer != NULL); while (ReadSize == PcdGet16(PcdShellFileOperationSize) && !EFI_ERROR(Status)) { Status = ShellReadFile(SourceHandle, &ReadSize, Buffer); Status = ShellWriteFile(DestHandle, &ReadSize, Buffer); } } SHELL_FREE_NON_NULL(DestVolumeInfo); } // // close files // if (DestHandle != NULL) { ShellCloseFile(&DestHandle); DestHandle = NULL; } if (SourceHandle != NULL) { ShellCloseFile(&SourceHandle); SourceHandle = NULL; } // // return // return (SHELL_SUCCESS); }
/** Verify that the TimeString is valid and if so set that as the current time. @param[in] TimeString The pointer to a string representation of the time. @param[in] Tz The value to set for TimeZone. @param[in] Daylight The value to set for Daylight. @retval SHELL_INVALID_PARAMETER TimeString was NULL. @retval SHELL_INVALID_PARAMETER TimeString was mis-formatted. @retval SHELL_SUCCESS The operation was successful. **/ SHELL_STATUS CheckAndSetTime ( IN CONST CHAR16 *TimeString, IN CONST INT16 Tz, IN CONST UINT8 Daylight ) { EFI_TIME TheTime; EFI_STATUS Status; CHAR16 *TimeStringCopy; CHAR16 *Walker1; CHAR16 *Walker2; if (TimeString != NULL && !InternalIsTimeLikeString(TimeString, L':', 1, 2, FALSE)) { return (SHELL_INVALID_PARAMETER); } if (Daylight != 0xFF &&((Daylight & (EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT)) != Daylight)) { return (SHELL_INVALID_PARAMETER); } Status = gRT->GetTime(&TheTime, NULL); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"time", L"gRT->GetTime", Status); return (SHELL_DEVICE_ERROR); } if (TimeString != NULL) { TimeStringCopy = NULL; TimeStringCopy = StrnCatGrow(&TimeStringCopy, NULL, TimeString, 0); Walker1 = TimeStringCopy; TheTime.Hour = 0xFF; TheTime.Minute = 0xFF; Walker2 = Walker1!=NULL?StrStr(Walker1, L":"):NULL; if (Walker2 != NULL && *Walker2 == L':') { *Walker2 = CHAR_NULL; } TheTime.Hour = (UINT8)ShellStrToUintn (Walker1); if (Walker2 != NULL) { Walker1 = Walker2 + 1; } Walker2 = Walker1!=NULL?StrStr(Walker1, L":"):NULL; if (Walker2 != NULL && *Walker2 == L':') { *Walker2 = CHAR_NULL; TheTime.Second = (UINT8)0; } else if (Walker2 == NULL) { TheTime.Second = (UINT8)0; } if (Walker1 != NULL && Walker1[0] != CHAR_NULL) { TheTime.Minute = (UINT8)ShellStrToUintn (Walker1); if (Walker2 != NULL) { Walker1 = Walker2 + 1; if (Walker1 != NULL && Walker1[0] != CHAR_NULL) { TheTime.Second = (UINT8)ShellStrToUintn (Walker1); } } } SHELL_FREE_NON_NULL(TimeStringCopy); } if (Tz >= -1440 && Tz <= 1440) { // // EFI_TIME TimeZone is stored to meet the following calculation (see UEFI Spec): // Localtime = UTC - TimeZone // This means the sign must be changed for the user provided Tz. // EX: User wants to set TimeZone to Pacific Standard Time, so runs // time -tz -480 # set to UTC-08:00 // To meet the calculation, the sign must be changed. // TheTime.TimeZone = -Tz; } else if (Tz == EFI_UNSPECIFIED_TIMEZONE) { TheTime.TimeZone = Tz; } if (Daylight != 0xFF) { TheTime.Daylight = Daylight; } Status = gRT->SetTime(&TheTime); if (!EFI_ERROR(Status)){ return (SHELL_SUCCESS); } return (SHELL_INVALID_PARAMETER); }
/** Function to take a destination path that might contain wildcards and verify that there is only a single possible target (IE we cant have wildcards that have 2 possible destination). if the result is sucessful the caller must free *DestPathPointer. @param[in] DestParameter The original path to the destination. @param[in, out] DestPathPointer A pointer to the callee allocated final path. @param[in] Cwd A pointer to the current working directory. @param[in] SingleSource TRUE to have only one source file. @param[in, out] DestAttr A pointer to the destination information attribute. @retval SHELL_INVALID_PARAMETER The DestParameter could not be resolved to a location. @retval SHELL_INVALID_PARAMETER The DestParameter could be resolved to more than 1 location. @retval SHELL_INVALID_PARAMETER Cwd is required and is NULL. @retval SHELL_SUCCESS The operation was sucessful. **/ SHELL_STATUS EFIAPI GetDestinationLocation( IN CONST CHAR16 *DestParameter, IN OUT CHAR16 **DestPathPointer, IN CONST CHAR16 *Cwd, IN CONST BOOLEAN SingleSource, IN OUT UINT64 *DestAttr ) { EFI_SHELL_FILE_INFO *DestList; EFI_SHELL_FILE_INFO *Node; CHAR16 *DestPath; UINTN NewSize; UINTN CurrentSize; DestList = NULL; DestPath = NULL; ASSERT(DestAttr != NULL); if (StrStr(DestParameter, L"\\") == DestParameter) { if (Cwd == NULL) { return SHELL_INVALID_PARAMETER; } DestPath = AllocateZeroPool(StrSize(Cwd)); if (DestPath == NULL) { return (SHELL_OUT_OF_RESOURCES); } StrCpyS(DestPath, StrSize(Cwd) / sizeof(CHAR16), Cwd); while (PathRemoveLastItem(DestPath)) ; // // Append DestParameter beyond '\' which may be present // CurrentSize = StrSize(DestPath); StrnCatGrow(&DestPath, &CurrentSize, &DestParameter[1], 0); *DestPathPointer = DestPath; return (SHELL_SUCCESS); } // // get the destination path // ShellOpenFileMetaArg((CHAR16*)DestParameter, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE, &DestList); if (DestList == NULL || IsListEmpty(&DestList->Link)) { // // Not existing... must be renaming // if (StrStr(DestParameter, L":") == NULL) { if (Cwd == NULL) { ShellCloseFileMetaArg(&DestList); ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle); return (SHELL_INVALID_PARAMETER); } NewSize = StrSize(Cwd); NewSize += StrSize(DestParameter); DestPath = AllocateZeroPool(NewSize); if (DestPath == NULL) { ShellCloseFileMetaArg(&DestList); return (SHELL_OUT_OF_RESOURCES); } StrCpyS(DestPath, NewSize / sizeof(CHAR16), Cwd); if (DestPath[StrLen(DestPath)-1] != L'\\' && DestParameter[0] != L'\\') { StrCatS(DestPath, NewSize / sizeof(CHAR16), L"\\"); } else if (DestPath[StrLen(DestPath)-1] == L'\\' && DestParameter[0] == L'\\') { ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; } StrCatS(DestPath, NewSize / sizeof(CHAR16), DestParameter); } else { ASSERT(DestPath == NULL); DestPath = StrnCatGrow(&DestPath, NULL, DestParameter, 0); if (DestPath == NULL) { ShellCloseFileMetaArg(&DestList); return (SHELL_OUT_OF_RESOURCES); } } } else { Node = (EFI_SHELL_FILE_INFO*)GetFirstNode(&DestList->Link); *DestAttr = Node->Info->Attribute; // // Make sure there is only 1 node in the list. // if (!IsNodeAtEnd(&DestList->Link, &Node->Link)) { ShellCloseFileMetaArg(&DestList); ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_MARG_ERROR), gShellLevel2HiiHandle, L"mv", DestParameter); return (SHELL_INVALID_PARAMETER); } // // If we are a directory or a single file, then one node is fine. // if (ShellIsDirectory(Node->FullName)==EFI_SUCCESS || SingleSource) { DestPath = AllocateZeroPool(StrSize(Node->FullName)+sizeof(CHAR16)); if (DestPath == NULL) { ShellCloseFileMetaArg(&DestList); return (SHELL_OUT_OF_RESOURCES); } StrCpyS(DestPath, (StrSize(Node->FullName)+sizeof(CHAR16)) / sizeof(CHAR16), Node->FullName); StrCatS(DestPath, (StrSize(Node->FullName)+sizeof(CHAR16)) / sizeof(CHAR16), L"\\"); } else { // // cant move multiple files onto a single file. // ShellCloseFileMetaArg(&DestList); ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_ERROR), gShellLevel2HiiHandle, L"mv", DestParameter); return (SHELL_INVALID_PARAMETER); } } *DestPathPointer = DestPath; ShellCloseFileMetaArg(&DestList); return (SHELL_SUCCESS); }
/** Verify that the TimeZoneString is valid and if so set that as the current timezone. @param[in] TimeZoneString The pointer to a string representation of the timezone. @retval SHELL_INVALID_PARAMETER TimeZoneString was NULL. @retval SHELL_INVALID_PARAMETER TimeZoneString was mis-formatted. @retval SHELL_SUCCESS The operation was successful. **/ SHELL_STATUS CheckAndSetTimeZone ( IN CONST CHAR16 *TimeZoneString ) { EFI_TIME TheTime; EFI_STATUS Status; CHAR16 *TimeZoneCopy; CHAR16 *Walker; CHAR16 *Walker2; UINTN LoopVar; if (TimeZoneString == NULL) { return (SHELL_INVALID_PARAMETER); } if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16 *)TimeZoneString, L"_local") == 0) { Status = gRT->GetTime (&TheTime, NULL); if (EFI_ERROR (Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"gRT->GetTime", Status); return (SHELL_DEVICE_ERROR); } TheTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE; Status = gRT->SetTime (&TheTime); if (!EFI_ERROR(Status)){ return (SHELL_SUCCESS); } return (SHELL_INVALID_PARAMETER); } if (TimeZoneString != NULL && !InternalIsTimeLikeString(TimeZoneString, L':', 1, 1, TRUE)) { return (SHELL_INVALID_PARAMETER); } Status = gRT->GetTime(&TheTime, NULL); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"timezone", L"gRT->GetTime", Status); return (SHELL_DEVICE_ERROR); } TimeZoneCopy = NULL; TimeZoneCopy = StrnCatGrow(&TimeZoneCopy, NULL, TimeZoneString, 0); if (TimeZoneCopy == NULL) { return (SHELL_OUT_OF_RESOURCES); } Walker = TimeZoneCopy; Walker2 = StrStr(Walker, L":"); if (Walker2 != NULL && *Walker2 == L':') { *Walker2 = CHAR_NULL; } if (*Walker == L'-') { TheTime.TimeZone = (INT16)((ShellStrToUintn (++Walker)) * 60); } else { TheTime.TimeZone = (INT16)((INT16)(ShellStrToUintn (Walker)) * -60); } if (Walker2 != NULL) { Walker = Walker2 + 1; } if (Walker != NULL && Walker[0] != CHAR_NULL) { if (TheTime.TimeZone < 0) { TheTime.TimeZone = (INT16)(TheTime.TimeZone - (UINT8)ShellStrToUintn (Walker)); } else { TheTime.TimeZone = (INT16)(TheTime.TimeZone + (UINT8)ShellStrToUintn (Walker)); } } Status = EFI_INVALID_PARAMETER; for ( LoopVar = 0 ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0]) ; LoopVar++ ){ if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) { Status = gRT->SetTime(&TheTime); break; } } FreePool(TimeZoneCopy); if (!EFI_ERROR(Status)){ return (SHELL_SUCCESS); } return (SHELL_INVALID_PARAMETER); }
IN CONST SCRIPT_COMMAND_LIST *CommandNode, IN OUT UINTN *TargetCount ) { BOOLEAN Found; CHAR16 *CommandName; CHAR16 *CommandNameWalker; CHAR16 *TempLocation; Found = FALSE; // // get just the first part of the command line... // CommandName = NULL; CommandName = StrnCatGrow(&CommandName, NULL, CommandNode->Cl, 0); if (CommandName == NULL) { return (FALSE); } CommandNameWalker = CommandName; while(CommandNameWalker[0] == L' ') { CommandNameWalker++; } TempLocation = StrStr(CommandNameWalker, L" "); if (TempLocation != NULL) { *TempLocation = CHAR_NULL; } //
/** Function for 'edit' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunEdit ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; CHAR16 *Buffer; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; LIST_ENTRY *Package; CONST CHAR16 *Cwd; CHAR16 *Nfs; CHAR16 *Spot; CONST CHAR16 *TempParam; // SHELL_FILE_HANDLE TempHandle; Buffer = NULL; ShellStatus = SHELL_SUCCESS; Nfs = NULL; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); Status = CommandInit(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"edit", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { if (ShellCommandLineGetCount(Package) > 2) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"edit"); ShellStatus = SHELL_INVALID_PARAMETER; } else { Cwd = gEfiShellProtocol->GetCurDir(NULL); if (Cwd == NULL) { Cwd = ShellGetEnvironmentVariable(L"path"); if (Cwd != NULL) { Nfs = StrnCatGrow(&Nfs, NULL, Cwd+3, 0); if (Nfs != NULL) { Spot = StrStr(Nfs, L";"); if (Spot != NULL) { *Spot = CHAR_NULL; } Spot = StrStr(Nfs, L"\\"); if (Spot != NULL) { Spot[1] = CHAR_NULL; } gEfiShellProtocol->SetCurDir(NULL, Nfs); FreePool(Nfs); } } } Status = MainEditorInit (); if (EFI_ERROR (Status)) { gST->ConOut->ClearScreen (gST->ConOut); gST->ConOut->EnableCursor (gST->ConOut, TRUE); ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_MAIN_INIT_FAILED), gShellDebug1HiiHandle); } else { MainEditorBackup (); // // if editor launched with file named // if (ShellCommandLineGetCount(Package) == 2) { TempParam = ShellCommandLineGetRawValue(Package, 1); ASSERT(TempParam != NULL); FileBufferSetFileName (TempParam); // if (EFI_ERROR(ShellFileExists(MainEditor.FileBuffer->FileName))) { // Status = ShellOpenFileByName(MainEditor.FileBuffer->FileName, &TempHandle, EFI_FILE_MODE_CREATE|EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0); // if (!EFI_ERROR(Status)) { // ShellCloseFile(&TempHandle); // } // } } Status = FileBufferRead (MainEditor.FileBuffer->FileName, FALSE); if (!EFI_ERROR (Status)) { MainEditorRefresh (); Status = MainEditorKeyInput (); } if (Status != EFI_OUT_OF_RESOURCES) { // // back up the status string // Buffer = CatSPrint (NULL, L"%s", StatusBarGetString()); } MainEditorCleanup (); // // print editor exit code on screen // if (Status == EFI_SUCCESS) { } else if (Status == EFI_OUT_OF_RESOURCES) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"edit"); } else { if (Buffer != NULL) { if (StrCmp (Buffer, L"") != 0) { // // print out the status string // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_MAIN_BUFFER), gShellDebug1HiiHandle, Buffer); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_MAIN_UNKNOWN_EDITOR_ERR), gShellDebug1HiiHandle); } } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_MAIN_UNKNOWN_EDITOR_ERR), gShellDebug1HiiHandle); } } if (Status != EFI_OUT_OF_RESOURCES) { SHELL_FREE_NON_NULL (Buffer); } } } ShellCommandLineFreeVarList (Package); } return ShellStatus; }