EFIAPI GetManFileName( IN CONST CHAR16 *ManFileName ) { CHAR16 *Buffer; if (ManFileName == NULL) { return (NULL); } // // Fix the file name // if (StrnCmp(ManFileName+StrLen(ManFileName)-4, L".man", 4)==0) { Buffer = AllocateCopyPool(StrSize(ManFileName), ManFileName); } else { Buffer = AllocateZeroPool(StrSize(ManFileName) + 4*sizeof(CHAR16)); if (Buffer != NULL) { StrnCpyS( Buffer, (StrSize(ManFileName) + 4*sizeof(CHAR16))/sizeof(CHAR16), ManFileName, StrLen(ManFileName) ); StrnCatS( Buffer, (StrSize(ManFileName) + 4*sizeof(CHAR16))/sizeof(CHAR16), L".man", 4 ); } } return (Buffer); }
/** This routine find the offset of the last period '.' of string. if No period exists function FileNameExtension is set to L'\0' @param[in] FileName File name to split between last period @param[out] FileNameFirst First FileName before last period @param[out] FileNameExtension FileName after last period **/ STATIC VOID SplitFileNameExtension ( IN CHAR16 *FileName, OUT CHAR16 *FileNameFirst, OUT CHAR16 *FileNameExtension ) { UINTN Index; UINTN StringLen; StringLen = StrLen(FileName); for (Index = StringLen; Index > 0 && FileName[Index] != L'.'; Index--); // // No period exists. No FileName Extension // if (Index == 0 && FileName[Index] != L'.') { FileNameExtension[0] = L'\0'; Index = StringLen; } else { StrCpyS (FileNameExtension, MAX_FILE_NAME_LEN, &FileName[Index+1]); } // // Copy First file name // StrnCpyS (FileNameFirst, MAX_FILE_NAME_LEN, FileName, Index); FileNameFirst[Index] = L'\0'; }
STATIC UINT32 FatHashLongName ( IN CHAR16 *LongNameString ) /*++ Routine Description: Get hash value for long name. Arguments: LongNameString - The long name string to be hashed. Returns: HashValue. --*/ { UINT32 HashValue; CHAR16 UpCasedLongFileName[EFI_PATH_STRING_LENGTH]; StrnCpyS ( UpCasedLongFileName, sizeof (UpCasedLongFileName) / sizeof (UpCasedLongFileName[0]), LongNameString, sizeof (UpCasedLongFileName) / sizeof (UpCasedLongFileName[0]) - 1 ); FatStrUpr (UpCasedLongFileName); gBS->CalculateCrc32 (UpCasedLongFileName, StrSize (UpCasedLongFileName), &HashValue); return (HashValue & HASH_TABLE_MASK); }
EFIAPI GetExecuatableFileName ( IN CONST CHAR16 *NameString ) { CHAR16 *Buffer; CHAR16 *SuffixStr; if (NameString == NULL) { return (NULL); } // // Fix the file name // if (StrnCmp(NameString+StrLen(NameString)-StrLen(L".efi"), L".efi", StrLen(L".efi"))==0) { Buffer = AllocateCopyPool(StrSize(NameString), NameString); } else if (StrnCmp(NameString+StrLen(NameString)-StrLen(L".man"), L".man", StrLen(L".man"))==0) { Buffer = AllocateCopyPool(StrSize(NameString), NameString); if (Buffer != NULL) { SuffixStr = Buffer+StrLen(Buffer)-StrLen(L".man"); StrnCpyS (SuffixStr, StrSize(L".man")/sizeof(CHAR16), L".efi", StrLen(L".efi")); } } else { Buffer = AllocateZeroPool(StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16)); if (Buffer != NULL) { StrnCpyS( Buffer, (StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16))/sizeof(CHAR16), NameString, StrLen(NameString) ); StrnCatS( Buffer, (StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16))/sizeof(CHAR16), L".efi", StrLen(L".efi") ); } } return (Buffer); }
/** Get a human readable name for an image. The following methods will be tried orderly: 1. Image PDB 2. FFS UI section 3. Image GUID @param[in] DriverInfo Pointer to memory profile driver info. @post The resulting Unicode name string is stored in the mNameString global array. **/ VOID GetDriverNameString ( IN MEMORY_PROFILE_DRIVER_INFO *DriverInfo ) { EFI_STATUS Status; CHAR8 *PdbFileName; CHAR16 *NameString; UINTN StringSize; // // Method 1: Get the name string from image PDB // if ((DriverInfo->ImageBase != 0) && (DriverInfo->FileType != EFI_FV_FILETYPE_SMM) && (DriverInfo->FileType != EFI_FV_FILETYPE_SMM_CORE)) { PdbFileName = PeCoffLoaderGetPdbPointer ((VOID *) (UINTN) DriverInfo->ImageBase); if (PdbFileName != NULL) { GetShortPdbFileName (PdbFileName, mNameString); return; } } if (!CompareGuid (&DriverInfo->FileName, &gZeroGuid)) { // // Try to get the image's FFS UI section by image GUID // NameString = NULL; StringSize = 0; Status = GetSectionFromAnyFv ( &DriverInfo->FileName, EFI_SECTION_USER_INTERFACE, 0, (VOID **) &NameString, &StringSize ); if (!EFI_ERROR (Status)) { // // Method 2: Get the name string from FFS UI section // StrnCpyS (mNameString, PROFILE_NAME_STRING_LENGTH + 1, NameString, PROFILE_NAME_STRING_LENGTH); mNameString[PROFILE_NAME_STRING_LENGTH] = 0; FreePool (NameString); return; } } // // Method 3: Get the name string from image GUID // UnicodeSPrint (mNameString, sizeof (mNameString), L"%g", &DriverInfo->FileName); }
/** Get the file name portion of the Pdb File Name. The portion of the Pdb File Name between the last backslash and either a following period or the end of the string is converted to Unicode and copied into UnicodeBuffer. The name is truncated, if necessary, to ensure that UnicodeBuffer is not overrun. @param[in] PdbFileName Pdb file name. @param[out] UnicodeBuffer The resultant Unicode File Name. **/ VOID DpGetShortPdbFileName ( IN CHAR8 *PdbFileName, OUT CHAR16 *UnicodeBuffer ) { UINTN IndexA; // Current work location within an ASCII string. UINTN IndexU; // Current work location within a Unicode string. UINTN StartIndex; UINTN EndIndex; ZeroMem (UnicodeBuffer, (DP_GAUGE_STRING_LENGTH + 1) * sizeof (CHAR16)); if (PdbFileName == NULL) { StrnCpyS (UnicodeBuffer, DP_GAUGE_STRING_LENGTH + 1, L" ", 1); } else { StartIndex = 0; for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++) ; for (IndexA = 0; PdbFileName[IndexA] != 0; IndexA++) { if (PdbFileName[IndexA] == '\\') { StartIndex = IndexA + 1; } if (PdbFileName[IndexA] == '.') { EndIndex = IndexA; } } IndexU = 0; for (IndexA = StartIndex; IndexA < EndIndex; IndexA++) { UnicodeBuffer[IndexU] = (CHAR16) PdbFileName[IndexA]; IndexU++; if (IndexU >= DP_GAUGE_STRING_LENGTH) { UnicodeBuffer[DP_GAUGE_STRING_LENGTH] = 0; break; } } } }
/** Open the root directory on a volume. @param This A pointer to the volume to open the root directory. @param RootFile A pointer to the location to return the opened file handle for the root directory. @retval EFI_SUCCESS The device was opened. @retval EFI_UNSUPPORTED This volume does not support the requested file system type. @retval EFI_NO_MEDIA The device has no medium. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_ACCESS_DENIED The service denied access to the file. @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources. @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no longer supported. Any existing file handles for this volume are no longer valid. To access the files on the new medium, the volume must be reopened with OpenVolume(). **/ EFI_STATUS EFIAPI FvSimpleFileSystemOpenVolume ( IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, OUT EFI_FILE_PROTOCOL **RootFile ) { EFI_STATUS Status; FV_FILESYSTEM_FILE *Root; CHAR16 *UiSection; EFI_GUID NameGuid; EFI_FV_FILE_ATTRIBUTES Attributes; UINT32 Authentication; UINTN Key; EFI_FV_FILETYPE FileType; UINTN Size; FV_FILESYSTEM_INSTANCE *Instance; FV_FILESYSTEM_FILE_INFO *FvFileInfo; EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol; CHAR16 *Name; UINTN NameLen; UINTN NumChars; UINTN DestMax; Instance = FVFS_INSTANCE_FROM_SIMPLE_FS_THIS (This); Status = EFI_SUCCESS; if (Instance->Root == NULL) { // // Allocate file structure for root file // Root = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE)); if (Root == NULL) { return EFI_OUT_OF_RESOURCES; } Instance->Root = Root; Root->Instance = Instance; Root->Signature = FVFS_FILE_SIGNATURE; CopyMem (&Root->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate)); Root->FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO)); if (Root->FvFileInfo == NULL) { return EFI_OUT_OF_RESOURCES; } Root->FvFileInfo->FileInfo.Size = sizeof (EFI_FILE_INFO); Root->FvFileInfo->FileInfo.Attribute = EFI_FILE_DIRECTORY | EFI_FILE_READ_ONLY; // // Populate the instance's list of files. We consider anything a file that // has a UI_SECTION, which we consider to be its filename. // FvProtocol = Instance->FvProtocol; // // Allocate Key // Key = 0; do { FileType = EFI_FV_FILETYPE_ALL; Status = FvProtocol->GetNextFile ( FvProtocol, &Key, &FileType, &NameGuid, &Attributes, &Size ); if (EFI_ERROR (Status)) { ASSERT (Status == EFI_NOT_FOUND); break; } // // Get a file's name: If it has a UI section, use that, otherwise use // its NameGuid. // UiSection = NULL; Status = FvProtocol->ReadSection ( FvProtocol, &NameGuid, EFI_SECTION_USER_INTERFACE, 0, (VOID **)&UiSection, &Size, &Authentication ); if (!EFI_ERROR (Status)) { Name = UiSection; } else { Name = AllocateZeroPool (GUID_STRING_SIZE); if (Name == NULL) { return EFI_OUT_OF_RESOURCES; } NumChars = UnicodeSPrint (Name, GUID_STRING_SIZE, L"%g", &NameGuid); ASSERT ((NumChars + 1) * sizeof (CHAR16) == GUID_STRING_SIZE); } // // Found a file. // Allocate a file structure and populate it. // NameLen = StrSize (Name); if (FV_FILETYPE_IS_EXECUTABLE (FileType)) { NameLen += StrSize (L".efi") - sizeof (CHAR16); } FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO) + NameLen - sizeof (CHAR16)); if (FvFileInfo == NULL) { return EFI_OUT_OF_RESOURCES; } FvFileInfo->Signature = FVFS_FILE_INFO_SIGNATURE; InitializeListHead (&FvFileInfo->Link); CopyMem (&FvFileInfo->NameGuid, &NameGuid, sizeof (EFI_GUID)); FvFileInfo->Type = FileType; // // Add ".efi" to filenames of drivers and applications. // DestMax = NameLen / sizeof (CHAR16); Status = StrnCpyS (&FvFileInfo->FileInfo.FileName[0], DestMax, Name, StrLen (Name)); ASSERT_EFI_ERROR (Status); if (FV_FILETYPE_IS_EXECUTABLE (FileType)) { Status = StrnCatS (&FvFileInfo->FileInfo.FileName[0], DestMax, L".efi", StrLen (L".efi")); ASSERT_EFI_ERROR (Status); } FvFileInfo->FileInfo.Size = sizeof (EFI_FILE_INFO) + NameLen - sizeof (CHAR16); Status = FvFsGetFileSize (FvProtocol, FvFileInfo); ASSERT_EFI_ERROR (Status); FvFileInfo->FileInfo.PhysicalSize = FvFileInfo->FileInfo.FileSize; FvFileInfo->FileInfo.Attribute = EFI_FILE_READ_ONLY; InsertHeadList (&Instance->FileInfoHead, &FvFileInfo->Link); FreePool (Name); } while (TRUE); if (Status == EFI_NOT_FOUND) { Status = EFI_SUCCESS; } } Instance->Root->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance); *RootFile = &Instance->Root->FileProtocol; return Status; }
/** parses through the MAN file formatted Buffer and returns the "Brief Description" for the .TH section as specified by Command. If the command section is not found return EFI_NOT_FOUND. Upon a sucessful return the caller is responsible to free the memory in *BriefDesc @param[in] Handle Buffer to read from @param[in] Command name of command's section to find @param[in] BriefDesc pointer to pointer to string where description goes. @param[in] BriefSize pointer to size of allocated BriefDesc @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 ManBufferFindTitleSection( IN CHAR16 **Buffer, IN CONST CHAR16 *Command, IN CHAR16 **BriefDesc, IN UINTN *BriefSize ) { EFI_STATUS Status; CHAR16 *TitleString; CHAR16 *TitleEnd; CHAR16 *CurrentLocation; UINTN TitleLength; CONST CHAR16 StartString[] = L".TH "; CONST CHAR16 EndString[] = L" 0 "; if ( Buffer == NULL || Command == NULL || (BriefDesc != NULL && BriefSize == NULL) ){ return (EFI_INVALID_PARAMETER); } Status = EFI_SUCCESS; // // more characters for StartString and EndString // TitleLength = StrSize(Command) + (StrLen(StartString) + StrLen(EndString)) * sizeof(CHAR16); TitleString = AllocateZeroPool(TitleLength); if (TitleString == NULL) { return (EFI_OUT_OF_RESOURCES); } StrCpyS(TitleString, TitleLength/sizeof(CHAR16), StartString); StrCatS(TitleString, TitleLength/sizeof(CHAR16), Command); StrCatS(TitleString, TitleLength/sizeof(CHAR16), EndString); CurrentLocation = StrStr(*Buffer, TitleString); if (CurrentLocation == NULL){ Status = EFI_NOT_FOUND; } else { // // we found it so copy out the rest of the line into BriefDesc // After skipping any spaces or zeroes // for (CurrentLocation += StrLen(TitleString) ; *CurrentLocation == L' ' || *CurrentLocation == L'0' || *CurrentLocation == L'1' || *CurrentLocation == L'\"' ; CurrentLocation++); TitleEnd = StrStr(CurrentLocation, L"\""); if (TitleEnd == NULL) { Status = EFI_DEVICE_ERROR; } else { if (BriefDesc != NULL) { *BriefSize = StrSize(TitleEnd); *BriefDesc = AllocateZeroPool(*BriefSize); if (*BriefDesc == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { StrnCpyS(*BriefDesc, (*BriefSize)/sizeof(CHAR16), CurrentLocation, TitleEnd-CurrentLocation); } } for (CurrentLocation = TitleEnd ; *CurrentLocation != L'\n' ; CurrentLocation++); for ( ; *CurrentLocation == L' ' || *CurrentLocation == L'\n' || *CurrentLocation == L'\r' ; CurrentLocation++); *Buffer = CurrentLocation; } } FreePool(TitleString); return (Status); }
/** Returns information about a file. @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle the requested information is for. @param InformationType The type identifier for the information being requested. @param BufferSize On input, the size of Buffer. On output, the amount of data returned in Buffer. In both cases, the size is measured in bytes. @param Buffer A pointer to the data buffer to return. The buffer's type is indicated by InformationType. @retval EFI_SUCCESS The information was returned. @retval EFI_UNSUPPORTED The InformationType is not known. @retval EFI_NO_MEDIA The device has no medium. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry. BufferSize has been updated with the size needed to complete the request. **/ EFI_STATUS EFIAPI FvSimpleFileSystemGetInfo ( IN EFI_FILE_PROTOCOL *This, IN EFI_GUID *InformationType, IN OUT UINTN *BufferSize, OUT VOID *Buffer ) { FV_FILESYSTEM_FILE *File; EFI_FILE_SYSTEM_INFO *FsInfoOut; EFI_FILE_SYSTEM_VOLUME_LABEL *FsVolumeLabel; FV_FILESYSTEM_INSTANCE *Instance; UINTN Size; EFI_STATUS Status; File = FVFS_FILE_FROM_FILE_THIS (This); if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { // // Return filesystem info // Instance = File->Instance; Size = sizeof (EFI_FILE_SYSTEM_INFO) + StrSize (Instance->VolumeLabel) - sizeof (CHAR16); if (*BufferSize < Size) { *BufferSize = Size; return EFI_BUFFER_TOO_SMALL; } // // Cast output buffer for convenience // FsInfoOut = (EFI_FILE_SYSTEM_INFO *) Buffer; CopyMem (FsInfoOut, &mFsInfoTemplate, sizeof (EFI_FILE_SYSTEM_INFO)); Status = StrnCpyS (FsInfoOut->VolumeLabel, (*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_INFO, VolumeLabel)) / sizeof (CHAR16), Instance->VolumeLabel, StrLen (Instance->VolumeLabel)); ASSERT_EFI_ERROR (Status); FsInfoOut->Size = Size; return Status; } else if (CompareGuid (InformationType, &gEfiFileInfoGuid)) { // // Return file info // return FvFsGetFileInfo (File->FvFileInfo, BufferSize, (EFI_FILE_INFO *) Buffer); } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { // // Return Volume Label // Instance = File->Instance; Size = sizeof (EFI_FILE_SYSTEM_VOLUME_LABEL) + StrSize (Instance->VolumeLabel) - sizeof (CHAR16);; if (*BufferSize < Size) { *BufferSize = Size; return EFI_BUFFER_TOO_SMALL; } FsVolumeLabel = (EFI_FILE_SYSTEM_VOLUME_LABEL*) Buffer; Status = StrnCpyS (FsVolumeLabel->VolumeLabel, (*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_VOLUME_LABEL, VolumeLabel)) / sizeof (CHAR16), Instance->VolumeLabel, StrLen (Instance->VolumeLabel)); ASSERT_EFI_ERROR (Status); return Status; } else { return EFI_UNSUPPORTED; } }
/** Get a human readable name for an image handle. The following methods will be tried orderly: 1. Image PDB 2. ComponentName2 protocol 3. FFS UI section 4. Image GUID 5. Image DevicePath 6. Unknown Driver Name @param[in] Handle @post The resulting Unicode name string is stored in the mGaugeString global array. **/ VOID DpGetNameFromHandle ( IN EFI_HANDLE Handle ) { EFI_STATUS Status; EFI_LOADED_IMAGE_PROTOCOL *Image; CHAR8 *PdbFileName; EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; EFI_STRING StringPtr; EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_GUID *NameGuid; CHAR16 *NameString; UINTN StringSize; CHAR8 *PlatformLanguage; EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2; Image = NULL; LoadedImageDevicePath = NULL; DevicePath = NULL; // // Method 1: Get the name string from image PDB // Status = gBS->HandleProtocol ( Handle, &gEfiLoadedImageProtocolGuid, (VOID **) &Image ); if (EFI_ERROR (Status)) { Status = gBS->OpenProtocol ( Handle, &gEfiDriverBindingProtocolGuid, (VOID **) &DriverBinding, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (!EFI_ERROR (Status)) { Status = gBS->HandleProtocol ( DriverBinding->ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &Image ); } } if (!EFI_ERROR (Status)) { PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase); if (PdbFileName != NULL) { DpGetShortPdbFileName (PdbFileName, mGaugeString); return; } } // // Method 2: Get the name string from ComponentName2 protocol // Status = gBS->HandleProtocol ( Handle, &gEfiComponentName2ProtocolGuid, (VOID **) &ComponentName2 ); if (!EFI_ERROR (Status)) { // // Get the current platform language setting // PlatformLanguage = GetBestLanguageForDriver(ComponentName2->SupportedLanguages, NULL, FALSE); Status = ComponentName2->GetDriverName ( ComponentName2, PlatformLanguage != NULL ? PlatformLanguage : "en-US", &StringPtr ); if (!EFI_ERROR (Status)) { SHELL_FREE_NON_NULL (PlatformLanguage); StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, StringPtr, DP_GAUGE_STRING_LENGTH); mGaugeString[DP_GAUGE_STRING_LENGTH] = 0; return; } } Status = gBS->HandleProtocol ( Handle, &gEfiLoadedImageDevicePathProtocolGuid, (VOID **) &LoadedImageDevicePath ); if (!EFI_ERROR (Status) && (LoadedImageDevicePath != NULL)) { DevicePath = LoadedImageDevicePath; } else if (Image != NULL) { DevicePath = Image->FilePath; } if (DevicePath != NULL) { // // Try to get image GUID from image DevicePath // NameGuid = NULL; while (!IsDevicePathEndType (DevicePath)) { NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePath); if (NameGuid != NULL) { break; } DevicePath = NextDevicePathNode (DevicePath); } if (NameGuid != NULL) { // // Try to get the image's FFS UI section by image GUID // NameString = NULL; StringSize = 0; Status = GetSectionFromAnyFv ( NameGuid, EFI_SECTION_USER_INTERFACE, 0, (VOID **) &NameString, &StringSize ); if (!EFI_ERROR (Status)) { // // Method 3. Get the name string from FFS UI section // StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, NameString, DP_GAUGE_STRING_LENGTH); mGaugeString[DP_GAUGE_STRING_LENGTH] = 0; FreePool (NameString); } else { // // Method 4: Get the name string from image GUID // UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", NameGuid); } return; } else { // // Method 5: Get the name string from image DevicePath // NameString = ConvertDevicePathToText (DevicePath, TRUE, FALSE); if (NameString != NULL) { StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, NameString, DP_GAUGE_STRING_LENGTH); mGaugeString[DP_GAUGE_STRING_LENGTH] = 0; FreePool (NameString); return; } } } // // Method 6: Unknown Driver Name // StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_ERROR_NAME), NULL); ASSERT (StringPtr != NULL); StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, StringPtr, DP_GAUGE_STRING_LENGTH); FreePool (StringPtr); }
/** Return the next parameter from a command line string. This function moves the next parameter from Walker into TempParameter and moves Walker up past that parameter for recursive calling. When the final parameter is moved *Walker will be set to NULL; Temp Parameter must be large enough to hold the parameter before calling this function. This will also remove all remaining ^ characters after processing. @param[in, out] Walker pointer to string of command line. Adjusted to reminaing command line on return @param[in, out] TempParameter pointer to string of command line item extracted. @param[in] Length buffer size of TempParameter. @return EFI_INALID_PARAMETER A required parameter was NULL or pointed to a NULL or empty string. @return EFI_NOT_FOUND A closing " could not be found on the specified string **/ EFI_STATUS EFIAPI GetNextParameter( IN OUT CHAR16 **Walker, IN OUT CHAR16 **TempParameter, IN CONST UINTN Length ) { CONST CHAR16 *NextDelim; if (Walker == NULL ||*Walker == NULL ||TempParameter == NULL ||*TempParameter == NULL ){ return (EFI_INVALID_PARAMETER); } // // make sure we dont have any leading spaces // while ((*Walker)[0] == L' ') { (*Walker)++; } // // make sure we still have some params now... // if (StrLen(*Walker) == 0) { DEBUG_CODE_BEGIN(); *Walker = NULL; DEBUG_CODE_END(); return (EFI_INVALID_PARAMETER); } NextDelim = FindEndOfParameter(*Walker); if (NextDelim == NULL){ DEBUG_CODE_BEGIN(); *Walker = NULL; DEBUG_CODE_END(); return (EFI_NOT_FOUND); } StrnCpyS(*TempParameter, Length / sizeof(CHAR16), (*Walker), NextDelim - *Walker); // // Add a CHAR_NULL if we didnt get one via the copy // if (*NextDelim != CHAR_NULL) { (*TempParameter)[NextDelim - *Walker] = CHAR_NULL; } // // Update Walker for the next iteration through the function // *Walker = (CHAR16*)NextDelim; // // Remove any non-escaped quotes in the string // Remove any remaining escape characters in the string // for (NextDelim = FindFirstCharacter(*TempParameter, L"\"^", CHAR_NULL) ; *NextDelim != CHAR_NULL ; NextDelim = FindFirstCharacter(NextDelim, L"\"^", CHAR_NULL) ) { if (*NextDelim == L'^') { // // eliminate the escape ^ // CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1)); NextDelim++; } else if (*NextDelim == L'\"') { // // eliminate the unescaped quote // CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1)); } } return EFI_SUCCESS; }
/** Function for 'drivers' 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 ShellCommandRunDrivers ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; CHAR8 *Language; CONST CHAR16 *Lang; EFI_HANDLE *HandleList; EFI_HANDLE *HandleWalker; UINTN ChildCount; UINTN DeviceCount; CHAR16 *Temp2; CONST CHAR16 *FullDriverName; CHAR16 *TruncatedDriverName; CHAR16 *FormatString; UINT32 DriverVersion; BOOLEAN DriverConfig; BOOLEAN DriverDiag; BOOLEAN SfoFlag; ShellStatus = SHELL_SUCCESS; Status = EFI_SUCCESS; Language = NULL; FormatString = NULL; SfoFlag = 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), gShellDriver1HiiHandle, L"drivers", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { if (ShellCommandLineGetCount(Package) > 1) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"drivers"); ShellStatus = SHELL_INVALID_PARAMETER; } else { if (ShellCommandLineGetFlag(Package, L"-l")){ Lang = ShellCommandLineGetValue(Package, L"-l"); if (Lang != NULL) { Language = AllocateZeroPool(StrSize(Lang)); AsciiSPrint(Language, StrSize(Lang), "%S", Lang); } else { ASSERT(Language == NULL); ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drivers", L"-l"); ShellCommandLineFreeVarList (Package); return (SHELL_INVALID_PARAMETER); } } if (ShellCommandLineGetFlag (Package, L"-sfo")) { SfoFlag = TRUE; FormatString = HiiGetString (gShellDriver1HiiHandle, STRING_TOKEN (STR_DRIVERS_ITEM_LINE_SFO), Language); // // print the SFO header // ShellPrintHiiEx ( -1, -1, Language, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellDriver1HiiHandle, L"drivers"); } else { FormatString = HiiGetString (gShellDriver1HiiHandle, STRING_TOKEN (STR_DRIVERS_ITEM_LINE), Language); // // print the header row // ShellPrintHiiEx( -1, -1, Language, STRING_TOKEN (STR_DRIVERS_HEADER_LINES), gShellDriver1HiiHandle); } HandleList = GetHandleListByProtocol(&gEfiDriverBindingProtocolGuid); for (HandleWalker = HandleList ; HandleWalker != NULL && *HandleWalker != NULL ; HandleWalker++){ ChildCount = 0; DeviceCount = 0; Status = ParseHandleDatabaseForChildDevices (*HandleWalker, &ChildCount , NULL); Status = PARSE_HANDLE_DATABASE_DEVICES (*HandleWalker, &DeviceCount, NULL); Temp2 = GetDevicePathTextForHandle(*HandleWalker); DriverVersion = ReturnDriverVersion(*HandleWalker); DriverConfig = ReturnDriverConfig(*HandleWalker); DriverDiag = ReturnDriverDiag (*HandleWalker); FullDriverName = GetStringNameFromHandle(*HandleWalker, Language); TruncatedDriverName = NULL; if (!SfoFlag && (FullDriverName != NULL)) { TruncatedDriverName = AllocateZeroPool ((MAX_LEN_DRIVER_NAME + 1) * sizeof (CHAR16)); StrnCpyS (TruncatedDriverName, MAX_LEN_DRIVER_NAME + 1, FullDriverName, MAX_LEN_DRIVER_NAME); } ShellPrintEx( -1, -1, FormatString, ConvertHandleToHandleIndex(*HandleWalker), DriverVersion, ChildCount > 0?L'B':(DeviceCount > 0?L'D':L'?'), DriverConfig?L'Y':L'N', DriverDiag?L'Y':L'N', DeviceCount, ChildCount, SfoFlag?FullDriverName:TruncatedDriverName, Temp2==NULL?L"":Temp2 ); if (TruncatedDriverName != NULL) { FreePool (TruncatedDriverName); } if (Temp2 != NULL) { FreePool(Temp2); } if (ShellGetExecutionBreakFlag ()) { ShellStatus = SHELL_ABORTED; break; } } } SHELL_FREE_NON_NULL(Language); ShellCommandLineFreeVarList (Package); SHELL_FREE_NON_NULL(FormatString); } return (ShellStatus); }
/** Get string or password input from user. @param MenuOption Pointer to the current input menu. @param Prompt The prompt string shown on popup window. @param StringPtr Old user input and destination for use input string. @retval EFI_SUCCESS If string input is read successfully @retval EFI_DEVICE_ERROR If operation fails **/ EFI_STATUS ReadString ( IN UI_MENU_OPTION *MenuOption, IN CHAR16 *Prompt, IN OUT CHAR16 *StringPtr ) { EFI_STATUS Status; EFI_INPUT_KEY Key; CHAR16 NullCharacter; UINTN ScreenSize; CHAR16 Space[2]; CHAR16 KeyPad[2]; CHAR16 *TempString; CHAR16 *BufferedString; UINTN Index; UINTN Index2; UINTN Count; UINTN Start; UINTN Top; UINTN DimensionsWidth; UINTN DimensionsHeight; UINTN CurrentCursor; BOOLEAN CursorVisible; UINTN Minimum; UINTN Maximum; FORM_DISPLAY_ENGINE_STATEMENT *Question; BOOLEAN IsPassword; UINTN MaxLen; DimensionsWidth = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn; DimensionsHeight = gStatementDimensions.BottomRow - gStatementDimensions.TopRow; NullCharacter = CHAR_NULL; ScreenSize = GetStringWidth (Prompt) / sizeof (CHAR16); Space[0] = L' '; Space[1] = CHAR_NULL; Question = MenuOption->ThisTag; GetFieldFromOp(Question->OpCode, &Minimum, &Maximum); if (Question->OpCode->OpCode == EFI_IFR_PASSWORD_OP) { IsPassword = TRUE; } else { IsPassword = FALSE; } MaxLen = Maximum + 1; TempString = AllocateZeroPool (MaxLen * sizeof (CHAR16)); ASSERT (TempString); if (ScreenSize < (Maximum + 1)) { ScreenSize = Maximum + 1; } if ((ScreenSize + 2) > DimensionsWidth) { ScreenSize = DimensionsWidth - 2; } BufferedString = AllocateZeroPool (ScreenSize * 2); ASSERT (BufferedString); Start = (DimensionsWidth - ScreenSize - 2) / 2 + gStatementDimensions.LeftColumn + 1; Top = ((DimensionsHeight - 6) / 2) + gStatementDimensions.TopRow - 1; // // Display prompt for string // // CreateDialog (NULL, "", Prompt, Space, "", NULL); CreateMultiStringPopUp (ScreenSize, 4, &NullCharacter, Prompt, Space, &NullCharacter); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)); CursorVisible = gST->ConOut->Mode->CursorVisible; gST->ConOut->EnableCursor (gST->ConOut, TRUE); CurrentCursor = GetStringWidth (StringPtr) / 2 - 1; if (CurrentCursor != 0) { // // Show the string which has beed saved before. // SetUnicodeMem (BufferedString, ScreenSize - 1, L' '); PrintStringAt (Start + 1, Top + 3, BufferedString); if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) { Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2; } else { Index = 0; } if (IsPassword) { gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3); } for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) { BufferedString[Count] = StringPtr[Index]; if (IsPassword) { PrintCharAt ((UINTN)-1, (UINTN)-1, L'*'); } } if (!IsPassword) { PrintStringAt (Start + 1, Top + 3, BufferedString); } gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->SetCursorPosition (gST->ConOut, Start + GetStringWidth (StringPtr) / 2, Top + 3); } do { Status = WaitForKeyStroke (&Key); ASSERT_EFI_ERROR (Status); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)); switch (Key.UnicodeChar) { case CHAR_NULL: switch (Key.ScanCode) { case SCAN_LEFT: if (CurrentCursor > 0) { CurrentCursor--; } break; case SCAN_RIGHT: if (CurrentCursor < (GetStringWidth (StringPtr) / 2 - 1)) { CurrentCursor++; } break; case SCAN_ESC: FreePool (TempString); FreePool (BufferedString); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); return EFI_DEVICE_ERROR; case SCAN_DELETE: for (Index = CurrentCursor; StringPtr[Index] != CHAR_NULL; Index++) { StringPtr[Index] = StringPtr[Index + 1]; PrintCharAt (Start + Index + 1, Top + 3, IsPassword && StringPtr[Index] != CHAR_NULL? L'*' : StringPtr[Index]); } break; default: break; } break; case CHAR_CARRIAGE_RETURN: if (GetStringWidth (StringPtr) >= ((Minimum + 1) * sizeof (CHAR16))) { FreePool (TempString); FreePool (BufferedString); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); return EFI_SUCCESS; } else { // // Simply create a popup to tell the user that they had typed in too few characters. // To save code space, we can then treat this as an error and return back to the menu. // do { CreateDialog (&Key, &NullCharacter, gMiniString, gPressEnter, &NullCharacter, NULL); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); FreePool (TempString); FreePool (BufferedString); gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); return EFI_DEVICE_ERROR; } case CHAR_BACKSPACE: if (StringPtr[0] != CHAR_NULL && CurrentCursor != 0) { for (Index = 0; Index < CurrentCursor - 1; Index++) { TempString[Index] = StringPtr[Index]; } Count = GetStringWidth (StringPtr) / 2 - 1; if (Count >= CurrentCursor) { for (Index = CurrentCursor - 1, Index2 = CurrentCursor; Index2 < Count; Index++, Index2++) { TempString[Index] = StringPtr[Index2]; } TempString[Index] = CHAR_NULL; } // // Effectively truncate string by 1 character // StrCpyS (StringPtr, MaxLen, TempString); CurrentCursor --; } default: // // If it is the beginning of the string, don't worry about checking maximum limits // if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) { StrnCpyS (StringPtr, MaxLen, &Key.UnicodeChar, 1); CurrentCursor++; } else if ((GetStringWidth (StringPtr) < ((Maximum + 1) * sizeof (CHAR16))) && (Key.UnicodeChar != CHAR_BACKSPACE)) { KeyPad[0] = Key.UnicodeChar; KeyPad[1] = CHAR_NULL; Count = GetStringWidth (StringPtr) / 2 - 1; if (CurrentCursor < Count) { for (Index = 0; Index < CurrentCursor; Index++) { TempString[Index] = StringPtr[Index]; } TempString[Index] = CHAR_NULL; StrCatS (TempString, MaxLen, KeyPad); StrCatS (TempString, MaxLen, StringPtr + CurrentCursor); StrCpyS (StringPtr, MaxLen, TempString); } else { StrCatS (StringPtr, MaxLen, KeyPad); } CurrentCursor++; } // // If the width of the input string is now larger than the screen, we nee to // adjust the index to start printing portions of the string // SetUnicodeMem (BufferedString, ScreenSize - 1, L' '); PrintStringAt (Start + 1, Top + 3, BufferedString); if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) { Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2; } else { Index = 0; } if (IsPassword) { gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3); } for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) { BufferedString[Count] = StringPtr[Index]; if (IsPassword) { PrintCharAt ((UINTN)-1, (UINTN)-1, L'*'); } } if (!IsPassword) { PrintStringAt (Start + 1, Top + 3, BufferedString); } break; } gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); gST->ConOut->SetCursorPosition (gST->ConOut, Start + CurrentCursor + 1, Top + 3); } while (TRUE); }
/** Function for 'cd' 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 ShellCommandRunCd ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CONST CHAR16 *Cwd; CHAR16 *Path; CHAR16 *Drive; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; CONST CHAR16 *Param1; CHAR16 *Param1Copy; CHAR16 *Walker; CHAR16 *Splitter; CHAR16 *TempBuffer; UINTN TotalSize; ProblemParam = NULL; ShellStatus = SHELL_SUCCESS; Cwd = NULL; Path = NULL; Drive = NULL; Splitter = NULL; TempBuffer = NULL; TotalSize = 0; Status = CommandInit(); ASSERT_EFI_ERROR(Status); // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); 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), gShellLevel2HiiHandle, L"cd", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } // // check for "-?" // if (ShellCommandLineGetFlag(Package, L"-?")) { ASSERT(FALSE); } else if (ShellCommandLineGetRawValue(Package, 2) != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"cd"); ShellStatus = SHELL_INVALID_PARAMETER; } else { // // remember that param 0 is the command name // If there are 0 value parameters, then print the current directory // else If there are 2 value parameters, then print the error message // else If there is 1 value paramerer , then change the directory // Cwd = ShellGetCurrentDir (NULL); if (Cwd == NULL) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cd"); ShellStatus = SHELL_NOT_FOUND; } else { Param1 = ShellCommandLineGetRawValue (Package, 1); if (Param1 == NULL) { // // display the current directory // ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_CD_PRINT), gShellLevel2HiiHandle, Cwd); } else { Param1Copy = CatSPrint (NULL, L"%s", Param1, NULL); for (Walker = Param1Copy; Walker != NULL && *Walker != CHAR_NULL; Walker++) { if (*Walker == L'\"') { CopyMem (Walker, Walker + 1, StrSize(Walker) - sizeof(Walker[0])); } } if (Param1Copy != NULL && IsCurrentFileSystem (Param1Copy, Cwd)) { Status = ReplaceDriveWithCwd (&Param1Copy,Cwd); if (!EFI_ERROR (Status)) { Param1Copy = PathCleanUpDirectories (Param1Copy); } } else { // // Can't use cd command to change filesystem. // ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_CD_NF), gShellLevel2HiiHandle, L"cd"); Status = EFI_NOT_FOUND; } if (!EFI_ERROR(Status) && Param1Copy != NULL) { Splitter = StrStr (Cwd, L":"); if (Param1Copy[0] == L'\\') { // // Absolute Path on current drive letter. // TotalSize = ((Splitter - Cwd + 1) * sizeof(CHAR16)) + StrSize(Param1Copy); TempBuffer = AllocateZeroPool (TotalSize); if (TempBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { StrnCpyS (TempBuffer, TotalSize / sizeof(CHAR16), Cwd, (Splitter - Cwd + 1)); StrCatS (TempBuffer, TotalSize / sizeof(CHAR16), Param1Copy); FreePool (Param1Copy); Param1Copy = TempBuffer; TempBuffer = NULL; } } else { if (StrStr (Param1Copy,L":") == NULL) { TotalSize = StrSize (Cwd) + StrSize (Param1Copy); TempBuffer = AllocateZeroPool (TotalSize); if (TempBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { StrCpyS (TempBuffer, TotalSize / sizeof (CHAR16), Cwd); StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), L"\\"); StrCatS (TempBuffer, TotalSize / sizeof (CHAR16), Param1Copy); FreePool (Param1Copy); Param1Copy = PathCleanUpDirectories (TempBuffer); } } } } if (!EFI_ERROR(Status)) { Status = ExtractDriveAndPath (Param1Copy, &Drive, &Path); } if (!EFI_ERROR (Status) && Drive != NULL && Path != NULL) { if (EFI_ERROR(ShellIsDirectory (Param1Copy))) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cd", Param1Copy); ShellStatus = SHELL_NOT_FOUND; } else { Status = gEfiShellProtocol->SetCurDir (Drive, Path + 1); if (EFI_ERROR (Status)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cd", Param1Copy); ShellStatus = SHELL_NOT_FOUND; } } } if (Drive != NULL) { FreePool (Drive); } if (Path != NULL) { FreePool (Path); } FreePool (Param1Copy); } } } // // free the command line package // ShellCommandLineFreeVarList (Package); // // return the status // return (ShellStatus); }