/** Check whether a reset is needed, and finish the reset reminder feature. If a reset is needed, Popup a menu to notice user, and finish the feature according to the user selection. **/ VOID EFIAPI SetupResetReminder ( VOID ) { EFI_INPUT_KEY Key; CHAR16 *StringBuffer1; CHAR16 *StringBuffer2; // //check any reset required change is applied? if yes, reset system // if (IsResetRequired ()) { StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); ASSERT (StringBuffer1 != NULL); StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); ASSERT (StringBuffer2 != NULL); StrCpyS (StringBuffer1, MAX_STRING_LEN, L"Configuration changed. Reset to apply it Now."); StrCpyS (StringBuffer2, MAX_STRING_LEN, L"Press ENTER to reset"); // // Popup a menu to notice user // do { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); FreePool (StringBuffer1); FreePool (StringBuffer2); gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); } }
/** Function to take the destination path and target file name to generate the full destination path. @param[in] DestPath A pointer to the destination file path string. @param[out] FullDestPath A pointer to the full destination path string. @param[in] FileName Name string of the targe file. @retval SHELL_SUCCESS the files were all moved. @retval SHELL_INVALID_PARAMETER a parameter was invalid @retval SHELL_OUT_OF_RESOURCES a memory allocation failed **/ EFI_STATUS EFIAPI CreateFullDestPath( IN CONST CHAR16 **DestPath, OUT CHAR16 **FullDestPath, IN CONST CHAR16 *FileName ) { UINTN Size; if (FullDestPath == NULL || FileName == NULL || DestPath == NULL || *DestPath == NULL){ return (EFI_INVALID_PARAMETER); } Size = StrSize(*DestPath) + StrSize(FileName); *FullDestPath = AllocateZeroPool(Size); if (*FullDestPath == NULL){ return (EFI_OUT_OF_RESOURCES); } StrCpyS(*FullDestPath, Size / sizeof(CHAR16), *DestPath); if ((*FullDestPath)[StrLen(*FullDestPath)-1] != L'\\' && FileName[0] != L'\\') { StrCatS(*FullDestPath, Size / sizeof(CHAR16), L"\\"); } StrCatS(*FullDestPath, Size / sizeof(CHAR16), FileName); return (EFI_SUCCESS); }
/** 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'; }
/** Add the component name for the floppy device @param[in] FdcDev A pointer to the FDC_BLK_IO_DEV instance. **/ VOID AddName ( IN FDC_BLK_IO_DEV *FdcDev ) { CHAR16 FloppyDriveName[FLOPPY_DRIVE_NAME_LEN + 1]; if (!(FeaturePcdGet(PcdComponentNameDisable) && FeaturePcdGet(PcdComponentName2Disable))) { StrCpyS (FloppyDriveName, FLOPPY_DRIVE_NAME_LEN + 1, FLOPPY_DRIVE_NAME); FloppyDriveName[FLOPPY_DRIVE_NAME_LEN - 1] = (CHAR16) (L'0' + FdcDev->Disk); AddUnicodeString2 ( "eng", gIsaFloppyComponentName.SupportedLanguages, &FdcDev->ControllerNameTable, FloppyDriveName, TRUE ); AddUnicodeString2 ( "en", gIsaFloppyComponentName2.SupportedLanguages, &FdcDev->ControllerNameTable, FloppyDriveName, FALSE ); } }
/** 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 // StrCpyS (mNameString, PROFILE_NAME_STRING_LENGTH + 1, NameString); 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); }
/** Return the boot description for the controller. @param Handle Controller handle. @return The description string. **/ CHAR16 * BmGetBootDescription ( IN EFI_HANDLE Handle ) { LIST_ENTRY *Link; BM_BOOT_DESCRIPTION_ENTRY *Entry; CHAR16 *Description; CHAR16 *DefaultDescription; CHAR16 *Temp; UINTN Index; // // Firstly get the default boot description // DefaultDescription = NULL; for (Index = 0; Index < sizeof (mBmBootDescriptionHandlers) / sizeof (mBmBootDescriptionHandlers[0]); Index++) { DefaultDescription = mBmBootDescriptionHandlers[Index] (Handle); if (DefaultDescription != NULL) { // // Avoid description confusion between UEFI & Legacy boot option by adding "UEFI " prefix // ONLY for core provided boot description handler. // Temp = AllocatePool (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)); ASSERT (Temp != NULL); StrCpyS (Temp, (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)) / sizeof (CHAR16), mBmUefiPrefix); StrCatS (Temp, (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)) / sizeof (CHAR16), DefaultDescription); FreePool (DefaultDescription); DefaultDescription = Temp; break; } } ASSERT (DefaultDescription != NULL); // // Secondly query platform for the better boot description // for ( Link = GetFirstNode (&mPlatformBootDescriptionHandlers) ; !IsNull (&mPlatformBootDescriptionHandlers, Link) ; Link = GetNextNode (&mPlatformBootDescriptionHandlers, Link) ) { Entry = CR (Link, BM_BOOT_DESCRIPTION_ENTRY, Link, BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE); Description = Entry->Handler (Handle, DefaultDescription); if (Description != NULL) { FreePool (DefaultDescription); return Description; } } return DefaultDescription; }
/** Check whether a reset is needed,if reset is needed, Popup a menu to notice user. **/ VOID BmSetupResetReminder ( VOID ) { EFI_INPUT_KEY Key; CHAR16 *StringBuffer1; CHAR16 *StringBuffer2; EFI_STATUS Status; EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL *FormBrowserEx2; // // Use BrowserEx2 protocol to check whether reset is required. // Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid, NULL, (VOID **) &FormBrowserEx2); // //check any reset required change is applied? if yes, reset system // if (!EFI_ERROR(Status) && FormBrowserEx2->IsResetRequired ()) { StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); ASSERT (StringBuffer1 != NULL); StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); ASSERT (StringBuffer2 != NULL); StrCpyS (StringBuffer1, MAX_STRING_LEN, L"Configuration changed. Reset to apply it Now."); StrCpyS (StringBuffer2, MAX_STRING_LEN, L"Press ENTER to reset"); // // Popup a menu to notice user // do { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL); } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); FreePool (StringBuffer1); FreePool (StringBuffer2); gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); } }
/** Clear capsule status variable. @retval EFI_SUCCESS The capsule status variable is cleared. **/ EFI_STATUS ClearCapsuleStatusVariable ( VOID ) { EFI_STATUS Status; UINT32 Index; CHAR16 CapsuleVarName[20]; CHAR16 *TempVarName; BOOLEAN Found; StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CapsuleVarName[0]), L"Capsule"); TempVarName = CapsuleVarName + StrLen (CapsuleVarName); Index = 0; Found = FALSE; while (TRUE) { UnicodeSPrint (TempVarName, 5 * sizeof(CHAR16), L"%04x", Index); Status = gRT->SetVariable ( CapsuleVarName, &gEfiCapsuleReportGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, 0, (VOID *)NULL ); if (Status == EFI_NOT_FOUND) { // // There is no more capsule variables, quit // break; } Found = TRUE; Print (L"Clear %s %r\n", CapsuleVarName, Status); Index++; if (Index > 0xFFFF) { break; } } if (!Found) { Print (L"No any Capsule#### variable found\n"); } return EFI_SUCCESS; }
EFIAPI FileDevicePathToText(EFI_DEVICE_PATH_PROTOCOL *FilePathProto) { EFI_STATUS Status; FILEPATH_DEVICE_PATH *FilePath; CHAR16 FilePathText[256]; // possible problem: if filepath is bigger CHAR16 *OutFilePathText; INTN Size; INTN SizeAll; INTN i; FilePathText[0] = L'\0'; i = 4; SizeAll = 0; //PRINT("FilePathProto->Type: %d, SubType: %d, Length: %d\n", FilePathProto->Type, FilePathProto->SubType, DevicePathNodeLength(FilePathProto)); while (FilePathProto != NULL && FilePathProto->Type != END_DEVICE_PATH_TYPE && i > 0) { if (FilePathProto->Type == MEDIA_DEVICE_PATH && FilePathProto->SubType == MEDIA_FILEPATH_DP) { FilePath = (FILEPATH_DEVICE_PATH *) FilePathProto; Size = (DevicePathNodeLength(FilePathProto) - 4) / 2; if (SizeAll + Size < 256) { if (SizeAll > 0 && FilePathText[SizeAll / 2 - 2] != L'\\') { StrCatS(FilePathText, 256, L"\\"); } StrCatS(FilePathText, 256, FilePath->PathName); SizeAll = StrSize(FilePathText); } } FilePathProto = NextDevicePathNode(FilePathProto); //PRINT("FilePathProto->Type: %d, SubType: %d, Length: %d\n", FilePathProto->Type, FilePathProto->SubType, DevicePathNodeLength(FilePathProto)); i--; //PRINT("FilePathText: %s\n", FilePathText); } OutFilePathText = NULL; Size = StrSize(FilePathText); if (Size > 2) { // we are allocating mem here - should be released by caller Status = gBS->AllocatePool(EfiBootServicesData, Size, (VOID*)&OutFilePathText); if (Status == EFI_SUCCESS) { StrCpyS(OutFilePathText, Size/sizeof(CHAR16), FilePathText); } else { OutFilePathText = NULL; } } return OutFilePathText; }
/** Clear capsule status variable. @retval EFI_SUCCESS The capsule status variable is cleared. **/ EFI_STATUS ClearCapsuleStatusVariable ( VOID ) { EFI_STATUS Status; UINT32 Index; CHAR16 CapsuleVarName[20]; CHAR16 *TempVarName; StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CapsuleVarName[0]), L"Capsule"); TempVarName = CapsuleVarName + StrLen (CapsuleVarName); Index = 0; while (TRUE) { UnicodeSPrint (TempVarName, 5 * sizeof(CHAR16), L"%04x", Index); Status = gRT->SetVariable ( CapsuleVarName, &gEfiCapsuleReportGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, 0, (VOID *)NULL ); if (EFI_ERROR(Status)) { // // There is no capsule variables, quit // break; } Index++; if (Index > 0xFFFF) { break; } } return EFI_SUCCESS; }
/** Function will replace drive identifier with CWD. If FullPath begining with ':' is invalid path, then ASSERT. If FullPath not include dirve identifier , then do nothing. If FullPath likes "fs0:\xx" or "fs0:/xx" , then do nothing. If FullPath likes "fs0:xxx" or "fs0:", the drive replaced by CWD. @param[in, out] FullPath The pointer to the string containing the path. @param[in] Cwd Current directory. @retval EFI_SUCCESS Success. @retval EFI_OUT_OF_SOURCES A memory allocation failed. **/ EFI_STATUS ReplaceDriveWithCwd ( IN OUT CHAR16 **FullPath, IN CONST CHAR16 *Cwd ) { CHAR16 *Splitter; CHAR16 *TempBuffer; UINTN TotalSize; Splitter = NULL; TempBuffer = NULL; TotalSize = 0; if (FullPath == NULL || *FullPath == NULL) { return EFI_SUCCESS; } Splitter = StrStr (*FullPath, L":"); ASSERT(Splitter != *FullPath); if (Splitter != NULL && *(Splitter + 1) != L'\\' && *(Splitter + 1) != L'/') { TotalSize = StrSize (Cwd) + StrSize (Splitter + 1); TempBuffer = AllocateZeroPool (TotalSize); if (TempBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } StrCpyS (TempBuffer, TotalSize / sizeof(CHAR16), Cwd); StrCatS (TempBuffer, TotalSize / sizeof(CHAR16), L"\\"); StrCatS (TempBuffer, TotalSize / sizeof(CHAR16), Splitter + 1); FreePool(*FullPath); *FullPath = TempBuffer; } return EFI_SUCCESS; }
/** Initialize capsule update variables. **/ VOID InitCapsuleUpdateVariable ( VOID ) { EFI_STATUS Status; UINTN Index; CHAR16 CapsuleVarName[30]; CHAR16 *TempVarName; // // Clear all the capsule variables CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2... // as early as possible which will avoid the next time boot after the capsule update // will still into the capsule loop // StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CapsuleVarName[0]), EFI_CAPSULE_VARIABLE_NAME); TempVarName = CapsuleVarName + StrLen (CapsuleVarName); Index = 0; while (TRUE) { if (Index > 0) { UnicodeValueToString (TempVarName, 0, Index, 0); } Status = gRT->SetVariable ( CapsuleVarName, &gEfiCapsuleVendorGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, 0, (VOID *)NULL ); if (EFI_ERROR (Status)) { // // There is no capsule variables, quit // break; } Index++; } }
/** 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); }
/** This function create a currently loaded Boot Option from the BMM. It then appends this Boot Option to the end of the "BootOrder" list. It also append this Boot Opotion to the end of BootOptionMenu. @param CallbackData The BMM context data. @param NvRamMap The file explorer formset internal state. @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation. @retval EFI_SUCCESS If function completes successfully. **/ EFI_STATUS Var_UpdateBootOption ( IN BMM_CALLBACK_DATA *CallbackData, IN FILE_EXPLORER_NV_DATA *NvRamMap ) { UINT16 *BootOrderList = NULL; UINT16 *NewBootOrderList = NULL; UINTN BootOrderListSize; UINT16 BootString[10]; VOID *Buffer; UINTN BufferSize; UINT8 *Ptr; UINT16 Index; BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; BOOLEAN OptionalDataExist; EFI_STATUS Status; OptionalDataExist = FALSE; Index = BOpt_GetBootOptionNumber () ; UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index); if (NvRamMap->BootDescriptionData[0] == 0x0000) { StrCpyS (NvRamMap->BootDescriptionData, 10, BootString); } BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (NvRamMap->BootDescriptionData); BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList); if (NvRamMap->BootOptionalData[0] != 0x0000) { OptionalDataExist = TRUE; BufferSize += StrSize (NvRamMap->BootOptionalData); } Buffer = AllocateZeroPool (BufferSize); if (NULL == Buffer) { return EFI_OUT_OF_RESOURCES; } NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); if (NULL == NewMenuEntry) { FreePool(Buffer); return EFI_OUT_OF_RESOURCES; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; NewLoadContext->Deleted = FALSE; NewLoadContext->LoadOptionSize = BufferSize; Ptr = (UINT8 *) Buffer; NewLoadContext->LoadOption = Ptr; *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE; NewLoadContext->Attributes = *((UINT32 *) Ptr); NewLoadContext->IsActive = TRUE; NewLoadContext->ForceReconnect = (BOOLEAN) ((NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT)?1:0); Ptr += sizeof (UINT32); *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList); NewLoadContext->FilePathListLength = *((UINT16 *) Ptr); Ptr += sizeof (UINT16); CopyMem ( Ptr, NvRamMap->BootDescriptionData, StrSize (NvRamMap->BootDescriptionData) ); NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->BootDescriptionData)); ASSERT (NewLoadContext->Description != NULL); NewMenuEntry->DisplayString = NewLoadContext->Description; CopyMem ( NewLoadContext->Description, (VOID *) Ptr, StrSize (NvRamMap->BootDescriptionData) ); Ptr += StrSize (NvRamMap->BootDescriptionData); CopyMem ( Ptr, CallbackData->LoadContext->FilePathList, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList)); ASSERT (NewLoadContext->FilePathList != NULL); CopyMem ( NewLoadContext->FilePathList, (VOID *) Ptr, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewMenuEntry->HelpString = FileDevicePathToStr (NewLoadContext->FilePathList); NewMenuEntry->OptionNumber = Index; NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository ( CallbackData, BootOptionStrDepository ); NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->DisplayString, NULL); NewMenuEntry->HelpStringToken = GetStringTokenFromDepository ( CallbackData, BootOptionHelpStrDepository ); NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->HelpString, NULL); if (OptionalDataExist) { Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList); CopyMem (Ptr, NvRamMap->BootOptionalData, StrSize (NvRamMap->BootOptionalData)); } Status = gRT->SetVariable ( BootString, &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, BufferSize, Buffer ); if (!EFI_ERROR (Status)) { BootOrderList = BdsLibGetVariableAndSize ( L"BootOrder", &gEfiGlobalVariableGuid, &BootOrderListSize ); // ASSERT (BootOrderList != NULL); if (BootOrderList != NULL) { NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16)); // ASSERT (NewBootOrderList != NULL); if (NewBootOrderList != NULL) { CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize); NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index; } FreePool (BootOrderList); } Status = gRT->SetVariable ( L"BootOrder", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, BootOrderListSize + sizeof (UINT16), NewBootOrderList ); if (!EFI_ERROR (Status)) { FreePool (NewBootOrderList); NewBootOrderList = NULL; InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link); BootOptionMenu.MenuNumber++; // // Update "change driver order" page used data, append the new add driver // option at the end. // Index = 0; while (CallbackData->BmmFakeNvData.BootOptionOrder[Index] != 0) { Index++; } CallbackData->BmmFakeNvData.BootOptionOrder[Index] = (UINT32) (NewMenuEntry->OptionNumber + 1); NvRamMap->BootDescriptionData[0] = 0x0000; NvRamMap->BootOptionalData[0] = 0x0000; } } return EFI_SUCCESS; }
/** Delete a node and all nodes under it (including sub directories). @param[in] Node The node to start deleting with. @param[in] Quiet TRUE to print no messages. @retval SHELL_SUCCESS The operation was successful. @retval SHELL_ACCESS_DENIED A file was read only. @retval SHELL_ABORTED The abort message was received. @retval SHELL_DEVICE_ERROR A device error occured reading this Node. **/ SHELL_STATUS CascadeDelete( IN EFI_SHELL_FILE_INFO *Node, IN CONST BOOLEAN Quiet ) { SHELL_STATUS ShellStatus; EFI_SHELL_FILE_INFO *List; EFI_SHELL_FILE_INFO *Node2; EFI_STATUS Status; SHELL_PROMPT_RESPONSE *Resp; CHAR16 *TempName; UINTN NewSize; Resp = NULL; ShellStatus = SHELL_SUCCESS; List = NULL; Status = EFI_SUCCESS; if ((Node->Info->Attribute & EFI_FILE_READ_ONLY) == EFI_FILE_READ_ONLY) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DETELE_RO), gShellLevel2HiiHandle, L"rm", Node->FullName); return (SHELL_ACCESS_DENIED); } if ((Node->Info->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) { if (!IsDirectoryEmpty(Node->Handle)) { if (!Quiet) { Status = ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_RM_LOG_DELETE_CONF), gShellLevel2HiiHandle, Node->FullName); Status = ShellPromptForResponse(ShellPromptResponseTypeYesNo, NULL, (VOID**)&Resp); ASSERT(Resp != NULL); if (EFI_ERROR(Status) || *Resp != ShellPromptResponseYes) { SHELL_FREE_NON_NULL(Resp); return (SHELL_ABORTED); } SHELL_FREE_NON_NULL(Resp); } // // empty out the directory // Status = gEfiShellProtocol->FindFilesInDir(Node->Handle, &List); if (EFI_ERROR(Status)) { if (List!=NULL) { gEfiShellProtocol->FreeFileList(&List); } return (SHELL_DEVICE_ERROR); } for (Node2 = (EFI_SHELL_FILE_INFO *)GetFirstNode(&List->Link) ; !IsNull(&List->Link, &Node2->Link) ; Node2 = (EFI_SHELL_FILE_INFO *)GetNextNode(&List->Link, &Node2->Link) ){ // // skip the directory traversing stuff... // if (StrCmp(Node2->FileName, L".") == 0 || StrCmp(Node2->FileName, L"..") == 0) { continue; } Node2->Status = gEfiShellProtocol->OpenFileByName (Node2->FullName, &Node2->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE); if (EFI_ERROR(Node2->Status) && StrStr(Node2->FileName, L":") == NULL) { // // Update the node filename to have full path with file system identifier // NewSize = StrSize(Node->FullName) + StrSize(Node2->FullName); TempName = AllocateZeroPool(NewSize); if (TempName == NULL) { ShellStatus = SHELL_OUT_OF_RESOURCES; } else { StrCpyS(TempName, NewSize/sizeof(CHAR16), Node->FullName); TempName[StrStr(TempName, L":")+1-TempName] = CHAR_NULL; StrCatS(TempName, NewSize/sizeof(CHAR16), Node2->FullName); FreePool((VOID*)Node2->FullName); Node2->FullName = TempName; // // Now try again to open the file // Node2->Status = gEfiShellProtocol->OpenFileByName (Node2->FullName, &Node2->Handle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE); } } if (!EFI_ERROR(Node2->Status)) { ShellStatus = CascadeDelete(Node2, Quiet); } else if (ShellStatus == SHELL_SUCCESS) { ShellStatus = (SHELL_STATUS)(Node2->Status&(~0x80000000)); } if (ShellStatus != SHELL_SUCCESS) { if (List!=NULL) { gEfiShellProtocol->FreeFileList(&List); } return (ShellStatus); } } if (List!=NULL) { gEfiShellProtocol->FreeFileList(&List); } } } if (!(StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0)) { // // now delete the current node... // if (!Quiet) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE), gShellLevel2HiiHandle, Node->FullName); } Status = gEfiShellProtocol->DeleteFile(Node->Handle); Node->Handle = NULL; } // // We cant allow for the warning here! (Dont use EFI_ERROR Macro). // if (Status != EFI_SUCCESS){ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_ERR), gShellLevel2HiiHandle, Status); return (SHELL_ACCESS_DENIED); } else { if (!Quiet) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_RM_LOG_DELETE_COMP), gShellLevel2HiiHandle); } return (SHELL_SUCCESS); } }
/** Append file name to existing file name. @param Str1 The existing file name @param Str2 The file name to be appended @return Allocate a new string to hold the appended result. Caller is responsible to free the returned string. **/ CHAR16 * LibAppendFileName ( IN CHAR16 *Str1, IN CHAR16 *Str2 ) { UINTN Size1; UINTN Size2; UINTN MaxLen; CHAR16 *Str; CHAR16 *TmpStr; CHAR16 *Ptr; CHAR16 *LastSlash; Size1 = StrSize (Str1); Size2 = StrSize (Str2); // // Check overflow // if (((MAX_UINTN - Size1) < Size2) || ((MAX_UINTN - Size1 - Size2) < sizeof(CHAR16))) { return NULL; } MaxLen = (Size1 + Size2 + sizeof (CHAR16))/ sizeof (CHAR16); Str = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16)); ASSERT (Str != NULL); TmpStr = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16)); ASSERT (TmpStr != NULL); StrCpyS (Str, MaxLen, Str1); if (!((*Str == '\\') && (*(Str + 1) == 0))) { StrCatS (Str, MaxLen, L"\\"); } StrCatS (Str, MaxLen, Str2); Ptr = Str; LastSlash = Str; while (*Ptr != 0) { if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '.' && *(Ptr + 3) == L'\\') { // // Convert "\Name\..\" to "\" // DO NOT convert the .. if it is at the end of the string. This will // break the .. behavior in changing directories. // // // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings // that overlap. // StrCpyS (TmpStr, MaxLen, Ptr + 3); StrCpyS (LastSlash, MaxLen - ((UINTN) LastSlash - (UINTN) Str) / sizeof (CHAR16), TmpStr); Ptr = LastSlash; } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') { // // Convert a "\.\" to a "\" // // // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings // that overlap. // StrCpyS (TmpStr, MaxLen, Ptr + 2); StrCpyS (Ptr, MaxLen - ((UINTN) Ptr - (UINTN) Str) / sizeof (CHAR16), TmpStr); Ptr = LastSlash; } else if (*Ptr == '\\') { LastSlash = Ptr; } Ptr++; } FreePool (TmpStr); return Str; }
/** This function processes the results of changes in configuration. When user select a interactive opcode, this callback will be triggered. Based on the Question(QuestionId) that triggers the callback, the corresponding actions is performed. It handles: 1) Process the axtra action or exit file explorer when user select one file . 2) update of file content if a dir is selected. @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param Action Specifies the type of action taken by the browser. @param QuestionId A unique value which is sent to the original exporting driver so that it can identify the type of data to expect. @param Type The type of value for the question. @param Value A pointer to the data being sent to the original exporting driver. @param ActionRequest On return, points to the action requested by the callback function. @retval EFI_SUCCESS The callback successfully handled the action. @retval other error Error occur when parse one directory. **/ EFI_STATUS EFIAPI LibCallback ( IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN EFI_BROWSER_ACTION Action, IN EFI_QUESTION_ID QuestionId, IN UINT8 Type, IN EFI_IFR_TYPE_VALUE *Value, OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest ) { EFI_STATUS Status; BOOLEAN NeedExit; CHAR16 *NewFileName; CHAR16 *NewFolderName; NeedExit = TRUE; NewFileName = NULL; NewFolderName = NULL; if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) { // // Do nothing for other UEFI Action. Only do call back when data is changed. // return EFI_UNSUPPORTED; } if (Action == EFI_BROWSER_ACTION_CHANGED) { if ((Value == NULL) || (ActionRequest == NULL)) { return EFI_INVALID_PARAMETER; } if (QuestionId == KEY_VALUE_CREATE_FILE_AND_EXIT) { *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; if (!IsZeroBuffer (mNewFileName, sizeof (mNewFileName))) { Status = LibCreateNewFile (mNewFileName,TRUE); ZeroMem (mNewFileName,sizeof (mNewFileName)); } } if (QuestionId == KEY_VALUE_NO_CREATE_FILE_AND_EXIT) { ZeroMem (mNewFileName,sizeof (mNewFileName)); *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; } if (QuestionId == KEY_VALUE_CREATE_FOLDER_AND_EXIT) { *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; if (!IsZeroBuffer (mNewFolderName, sizeof (mNewFolderName))) { Status = LibCreateNewFile (mNewFolderName, FALSE); ZeroMem (mNewFolderName,sizeof (mNewFolderName)); } } if (QuestionId == KEY_VALUE_NO_CREATE_FOLDER_AND_EXIT) { ZeroMem (mNewFolderName,sizeof (mNewFolderName)); *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; } if (QuestionId == NEW_FILE_NAME_ID) { NewFileName = HiiGetString (gFileExplorerPrivate.FeHiiHandle, Value->string, NULL); if (NewFileName != NULL) { StrCpyS (mNewFileName, MAX_FILE_NAME_LEN, NewFileName); FreePool (NewFileName); NewFileName = NULL; } else { return EFI_INVALID_PARAMETER; } } if (QuestionId == NEW_FOLDER_NAME_ID) { NewFolderName = HiiGetString (gFileExplorerPrivate.FeHiiHandle, Value->string, NULL); if (NewFolderName != NULL) { StrCpyS (mNewFolderName, MAX_FOLDER_NAME_LEN, NewFolderName); FreePool (NewFolderName); NewFolderName = NULL; } else { return EFI_INVALID_PARAMETER; } } if (QuestionId >= FILE_OPTION_OFFSET) { LibGetDevicePath(QuestionId); // // Process the extra action. // if (gFileExplorerPrivate.ChooseHandler != NULL) { NeedExit = gFileExplorerPrivate.ChooseHandler (gFileExplorerPrivate.RetDevicePath); } if (NeedExit) { *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; } } } else if (Action == EFI_BROWSER_ACTION_CHANGING) { if (Value == NULL) { return EFI_INVALID_PARAMETER; } if (QuestionId >= FILE_OPTION_OFFSET) { LibGetDevicePath(QuestionId); Status = LibUpdateFileExplorer (QuestionId); if (EFI_ERROR (Status)) { return Status; } } } return EFI_SUCCESS; }
/** 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); }
/** Get the mac address string from the device path. if the device path has the vlan, get the vanid also. @param MacAddressNode Device path begin with mac address @param PBuffer Output string buffer contain mac address. **/ BOOLEAN GetMacAddressString( IN MAC_ADDR_DEVICE_PATH *MacAddressNode, OUT CHAR16 **PBuffer ) { UINTN HwAddressSize; UINTN Index; UINT8 *HwAddress; EFI_DEVICE_PATH_PROTOCOL *Node; UINT16 VlanId; CHAR16 *String; UINTN BufferLen; VlanId = 0; String = NULL; ASSERT(MacAddressNode != NULL); HwAddressSize = sizeof (EFI_MAC_ADDRESS); if (MacAddressNode->IfType == 0x01 || MacAddressNode->IfType == 0x00) { HwAddressSize = 6; } // // The output format is MAC:XX:XX:XX:...\XXXX // The size is the Number size + ":" size + Vlan size(\XXXX) + End // BufferLen = (4 + 2 * HwAddressSize + (HwAddressSize - 1) + 5 + 1) * sizeof (CHAR16); String = AllocateZeroPool (BufferLen); if (String == NULL) { return FALSE; } *PBuffer = String; StrCpyS(String, BufferLen / sizeof (CHAR16), L"MAC:"); String += 4; // // Convert the MAC address into a unicode string. // HwAddress = &MacAddressNode->MacAddress.Addr[0]; for (Index = 0; Index < HwAddressSize; Index++) { String += UnicodeValueToString (String, PREFIX_ZERO | RADIX_HEX, *(HwAddress++), 2); if (Index < HwAddressSize - 1) { *String++ = L':'; } } // // If VLAN is configured, it will need extra 5 characters like "\0005". // Plus one unicode character for the null-terminator. // Node = (EFI_DEVICE_PATH_PROTOCOL *)MacAddressNode; while (!IsDevicePathEnd (Node)) { if (Node->Type == MESSAGING_DEVICE_PATH && Node->SubType == MSG_VLAN_DP) { VlanId = ((VLAN_DEVICE_PATH *) Node)->VlanId; } Node = NextDevicePathNode (Node); } if (VlanId != 0) { *String++ = L'\\'; String += UnicodeValueToString (String, PREFIX_ZERO | RADIX_HEX, VlanId, 4); } // // Null terminate the Unicode string // *String = L'\0'; return TRUE; }
/** This function create a currently loaded Drive Option from the BMM. It then appends this Driver Option to the end of the "DriverOrder" list. It append this Driver Opotion to the end of DriverOptionMenu. @param CallbackData The BMM context data. @param HiiHandle The HII handle associated with the BMM formset. @param DescriptionData The description of this driver option. @param OptionalData The optional load option. @param ForceReconnect If to force reconnect. @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation. @retval EFI_SUCCESS If function completes successfully. **/ EFI_STATUS Var_UpdateDriverOption ( IN BMM_CALLBACK_DATA *CallbackData, IN EFI_HII_HANDLE HiiHandle, IN UINT16 *DescriptionData, IN UINT16 *OptionalData, IN UINT8 ForceReconnect ) { UINT16 Index; UINT16 *DriverOrderList; UINT16 *NewDriverOrderList; UINT16 DriverString[12]; UINTN DriverOrderListSize; VOID *Buffer; UINTN BufferSize; UINT8 *Ptr; BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; BOOLEAN OptionalDataExist; EFI_STATUS Status; OptionalDataExist = FALSE; Index = BOpt_GetDriverOptionNumber (); UnicodeSPrint ( DriverString, sizeof (DriverString), L"Driver%04x", Index ); if (*DescriptionData == 0x0000) { StrCpyS (DescriptionData, MAX_MENU_NUMBER, DriverString); } BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescriptionData); BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList); if (*OptionalData != 0x0000) { OptionalDataExist = TRUE; BufferSize += StrSize (OptionalData); } Buffer = AllocateZeroPool (BufferSize); if (NULL == Buffer) { return EFI_OUT_OF_RESOURCES; } NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); if (NULL == NewMenuEntry) { FreePool (Buffer); return EFI_OUT_OF_RESOURCES; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; NewLoadContext->Deleted = FALSE; NewLoadContext->LoadOptionSize = BufferSize; Ptr = (UINT8 *) Buffer; NewLoadContext->LoadOption = Ptr; *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE | (ForceReconnect << 1); NewLoadContext->Attributes = *((UINT32 *) Ptr); NewLoadContext->IsActive = TRUE; NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT); Ptr += sizeof (UINT32); *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList); NewLoadContext->FilePathListLength = *((UINT16 *) Ptr); Ptr += sizeof (UINT16); CopyMem ( Ptr, DescriptionData, StrSize (DescriptionData) ); NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData)); ASSERT (NewLoadContext->Description != NULL); NewMenuEntry->DisplayString = NewLoadContext->Description; CopyMem ( NewLoadContext->Description, (VOID *) Ptr, StrSize (DescriptionData) ); Ptr += StrSize (DescriptionData); CopyMem ( Ptr, CallbackData->LoadContext->FilePathList, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList)); ASSERT (NewLoadContext->FilePathList != NULL); CopyMem ( NewLoadContext->FilePathList, (VOID *) Ptr, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList); NewMenuEntry->OptionNumber = Index; NewMenuEntry->DisplayStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->DisplayString, NULL); NewMenuEntry->HelpStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->HelpString, NULL); if (OptionalDataExist) { Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList); CopyMem ( Ptr, OptionalData, StrSize (OptionalData) ); } Status = gRT->SetVariable ( DriverString, &gEfiGlobalVariableGuid, VAR_FLAG, BufferSize, Buffer ); ASSERT_EFI_ERROR (Status); GetEfiGlobalVariable2 (L"DriverOrder", (VOID **) &DriverOrderList, &DriverOrderListSize); NewDriverOrderList = AllocateZeroPool (DriverOrderListSize + sizeof (UINT16)); ASSERT (NewDriverOrderList != NULL); if (DriverOrderList != NULL){ CopyMem (NewDriverOrderList, DriverOrderList, DriverOrderListSize); } NewDriverOrderList[DriverOrderListSize / sizeof (UINT16)] = Index; if (DriverOrderList != NULL) { EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid); } Status = gRT->SetVariable ( L"DriverOrder", &gEfiGlobalVariableGuid, VAR_FLAG, DriverOrderListSize + sizeof (UINT16), NewDriverOrderList ); ASSERT_EFI_ERROR (Status); if (DriverOrderList != NULL) { FreePool (DriverOrderList); } DriverOrderList = NULL; FreePool (NewDriverOrderList); InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link); DriverOptionMenu.MenuNumber++; return EFI_SUCCESS; }
/** This function create a currently loaded Boot Option from the BMM. It then appends this Boot Option to the end of the "BootOrder" list. It also append this Boot Opotion to the end of BootOptionMenu. @param CallbackData The BMM context data. @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation. @retval EFI_SUCCESS If function completes successfully. **/ EFI_STATUS Var_UpdateBootOption ( IN BMM_CALLBACK_DATA *CallbackData ) { UINT16 *BootOrderList; UINT16 *NewBootOrderList; UINTN BootOrderListSize; UINT16 BootString[10]; VOID *Buffer; UINTN BufferSize; UINT8 *Ptr; UINT16 Index; BM_MENU_ENTRY *NewMenuEntry; BM_LOAD_CONTEXT *NewLoadContext; BOOLEAN OptionalDataExist; EFI_STATUS Status; BMM_FAKE_NV_DATA *NvRamMap; OptionalDataExist = FALSE; NvRamMap = &CallbackData->BmmFakeNvData; Index = BOpt_GetBootOptionNumber () ; UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index); if (NvRamMap->BootDescriptionData[0] == 0x0000) { StrCpyS (NvRamMap->BootDescriptionData, sizeof (NvRamMap->BootDescriptionData) / sizeof (NvRamMap->BootDescriptionData[0]), BootString); } BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (NvRamMap->BootDescriptionData); BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList); if (NvRamMap->BootOptionalData[0] != 0x0000) { OptionalDataExist = TRUE; BufferSize += StrSize (NvRamMap->BootOptionalData); } Buffer = AllocateZeroPool (BufferSize); if (NULL == Buffer) { return EFI_OUT_OF_RESOURCES; } NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT); if (NULL == NewMenuEntry) { return EFI_OUT_OF_RESOURCES; } NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext; NewLoadContext->Deleted = FALSE; NewLoadContext->LoadOptionSize = BufferSize; Ptr = (UINT8 *) Buffer; NewLoadContext->LoadOption = Ptr; *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE; NewLoadContext->Attributes = *((UINT32 *) Ptr); NewLoadContext->IsActive = TRUE; NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT); Ptr += sizeof (UINT32); *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList); NewLoadContext->FilePathListLength = *((UINT16 *) Ptr); Ptr += sizeof (UINT16); CopyMem ( Ptr, NvRamMap->BootDescriptionData, StrSize (NvRamMap->BootDescriptionData) ); NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->BootDescriptionData)); ASSERT (NewLoadContext->Description != NULL); NewMenuEntry->DisplayString = NewLoadContext->Description; CopyMem ( NewLoadContext->Description, (VOID *) Ptr, StrSize (NvRamMap->BootDescriptionData) ); Ptr += StrSize (NvRamMap->BootDescriptionData); CopyMem ( Ptr, CallbackData->LoadContext->FilePathList, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList)); ASSERT (NewLoadContext->FilePathList != NULL); CopyMem ( NewLoadContext->FilePathList, (VOID *) Ptr, GetDevicePathSize (CallbackData->LoadContext->FilePathList) ); NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList); NewMenuEntry->OptionNumber = Index; NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL); NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->HelpString, NULL); if (OptionalDataExist) { Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList); CopyMem (Ptr, NvRamMap->BootOptionalData, StrSize (NvRamMap->BootOptionalData)); } Status = gRT->SetVariable ( BootString, &gEfiGlobalVariableGuid, VAR_FLAG, BufferSize, Buffer ); ASSERT_EFI_ERROR (Status); GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrderList, &BootOrderListSize); NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16)); ASSERT (NewBootOrderList != NULL); if (BootOrderList != NULL){ CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize); } NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index; if (BootOrderList != NULL) { FreePool (BootOrderList); } Status = gRT->SetVariable ( L"BootOrder", &gEfiGlobalVariableGuid, VAR_FLAG, BootOrderListSize + sizeof (UINT16), NewBootOrderList ); ASSERT_EFI_ERROR (Status); FreePool (NewBootOrderList); NewBootOrderList = NULL; InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link); BootOptionMenu.MenuNumber++; return EFI_SUCCESS; }
/** function to take a list of files to copy and a destination location and do the verification and copying of those files to that location. This function will report any errors to the user and halt. The key is to have this function called ONLY once. this allows for the parameter verification to happen correctly. @param[in] FileList A LIST_ENTRY* based list of files to move. @param[in] DestDir The destination location. @param[in] SilentMode TRUE to eliminate screen output. @param[in] RecursiveMode TRUE to copy directories. @param[in] Resp The response to the overwrite query (if always). @retval SHELL_SUCCESS the files were all moved. @retval SHELL_INVALID_PARAMETER a parameter was invalid @retval SHELL_SECURITY_VIOLATION a security violation ocurred @retval SHELL_WRITE_PROTECTED the destination was write protected @retval SHELL_OUT_OF_RESOURCES a memory allocation failed **/ SHELL_STATUS ValidateAndCopyFiles( IN CONST EFI_SHELL_FILE_INFO *FileList, IN CONST CHAR16 *DestDir, IN BOOLEAN SilentMode, IN BOOLEAN RecursiveMode, IN VOID **Resp ) { CHAR16 *HiiOutput; CHAR16 *HiiResultOk; CONST EFI_SHELL_FILE_INFO *Node; SHELL_STATUS ShellStatus; EFI_STATUS Status; CHAR16 *DestPath; VOID *Response; UINTN PathSize; CONST CHAR16 *Cwd; UINTN NewSize; CHAR16 *CleanFilePathStr; if (Resp == NULL) { Response = NULL; } else { Response = *Resp; } DestPath = NULL; ShellStatus = SHELL_SUCCESS; PathSize = 0; Cwd = ShellGetCurrentDir(NULL); CleanFilePathStr = NULL; ASSERT(FileList != NULL); ASSERT(DestDir != NULL); Status = ShellLevel2StripQuotes (DestDir, &CleanFilePathStr); if (EFI_ERROR (Status)) { if (Status == EFI_OUT_OF_RESOURCES) { return SHELL_OUT_OF_RESOURCES; } else { return SHELL_INVALID_PARAMETER; } } ASSERT (CleanFilePathStr != NULL); // // If we are trying to copy multiple files... make sure we got a directory for the target... // if (EFI_ERROR(ShellIsDirectory(CleanFilePathStr)) && FileList->Link.ForwardLink != FileList->Link.BackLink) { // // Error for destination not a directory // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); FreePool (CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link) ; !IsNull(&FileList->Link, &Node->Link) ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link) ){ // // skip the directory traversing stuff... // if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) { continue; } NewSize = StrSize(CleanFilePathStr); NewSize += StrSize(Node->FullName); NewSize += (Cwd == NULL)? 0 : (StrSize(Cwd) + sizeof(CHAR16)); if (NewSize > PathSize) { PathSize = NewSize; } // // Make sure got -r if required // if (!RecursiveMode && !EFI_ERROR(ShellIsDirectory(Node->FullName))) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_REQ), gShellLevel2HiiHandle, L"cp"); FreePool (CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } // // make sure got dest as dir if needed // if (!EFI_ERROR(ShellIsDirectory(Node->FullName)) && EFI_ERROR(ShellIsDirectory(CleanFilePathStr))) { // // Error for destination not a directory // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); FreePool (CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } } HiiOutput = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_CP_OUTPUT), NULL); HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL); DestPath = AllocateZeroPool(PathSize); if (DestPath == NULL || HiiOutput == NULL || HiiResultOk == NULL) { SHELL_FREE_NON_NULL(DestPath); SHELL_FREE_NON_NULL(HiiOutput); SHELL_FREE_NON_NULL(HiiResultOk); FreePool (CleanFilePathStr); return (SHELL_OUT_OF_RESOURCES); } // // Go through the list of files to copy... // for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link) ; !IsNull(&FileList->Link, &Node->Link) ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link) ){ if (ShellGetExecutionBreakFlag()) { break; } ASSERT(Node->FileName != NULL); ASSERT(Node->FullName != NULL); // // skip the directory traversing stuff... // if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) { continue; } if (FileList->Link.ForwardLink == FileList->Link.BackLink // 1 item && EFI_ERROR(ShellIsDirectory(CleanFilePathStr)) // not an existing directory ) { if (StrStr(CleanFilePathStr, L":") == NULL) { // // simple copy of a single file // if (Cwd != NULL) { StrCpyS(DestPath, PathSize / sizeof(CHAR16), Cwd); StrCatS(DestPath, PathSize / sizeof(CHAR16), L"\\"); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); FreePool (CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } if (DestPath[StrLen(DestPath)-1] != L'\\' && CleanFilePathStr[0] != L'\\') { StrCatS(DestPath, PathSize / sizeof(CHAR16), L"\\"); } else if (DestPath[StrLen(DestPath)-1] == L'\\' && CleanFilePathStr[0] == L'\\') { ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; } StrCatS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr); } else { StrCpyS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr); } } else { // // we have multiple files or a directory in the DestDir // // // Check for leading slash // if (CleanFilePathStr[0] == L'\\') { // // Copy to the root of CWD // if (Cwd != NULL) { StrCpyS(DestPath, PathSize/sizeof(CHAR16), Cwd); StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); FreePool(CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } while (PathRemoveLastItem(DestPath)); StrCatS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr+1); StrCatS(DestPath, PathSize/sizeof(CHAR16), Node->FileName); } else if (StrStr(CleanFilePathStr, L":") == NULL) { if (Cwd != NULL) { StrCpyS(DestPath, PathSize/sizeof(CHAR16), Cwd); StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, L"cp", CleanFilePathStr); FreePool(CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } if (DestPath[StrLen(DestPath)-1] != L'\\' && CleanFilePathStr[0] != L'\\') { StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); } else if (DestPath[StrLen(DestPath)-1] == L'\\' && CleanFilePathStr[0] == L'\\') { ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; } StrCatS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr); if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] != L'\\' && Node->FileName[0] != L'\\') { StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); } else if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] == L'\\' && Node->FileName[0] == L'\\') { ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; } StrCatS(DestPath, PathSize/sizeof(CHAR16), Node->FileName); } else { StrCpyS(DestPath, PathSize/sizeof(CHAR16), CleanFilePathStr); if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] != L'\\' && Node->FileName[0] != L'\\') { StrCatS(DestPath, PathSize/sizeof(CHAR16), L"\\"); } else if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] == L'\\' && Node->FileName[0] == L'\\') { ((CHAR16*)CleanFilePathStr)[StrLen(CleanFilePathStr)-1] = CHAR_NULL; } StrCatS(DestPath, PathSize/sizeof(CHAR16), Node->FileName); } } // // Make sure the path exists // if (EFI_ERROR(VerifyIntermediateDirectories(DestPath))) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_WNF), gShellLevel2HiiHandle, L"cp", DestPath); ShellStatus = SHELL_DEVICE_ERROR; break; } if ( !EFI_ERROR(ShellIsDirectory(Node->FullName)) && !EFI_ERROR(ShellIsDirectory(DestPath)) && StrniCmp(Node->FullName, DestPath, StrLen(DestPath)) == NULL ){ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_PARENT), gShellLevel2HiiHandle, L"cp"); ShellStatus = SHELL_INVALID_PARAMETER; break; } if (StringNoCaseCompare(&Node->FullName, &DestPath) == 0) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle, L"cp"); ShellStatus = SHELL_INVALID_PARAMETER; break; } if ((StrniCmp(Node->FullName, DestPath, StrLen(Node->FullName)) == 0) && (DestPath[StrLen(Node->FullName)] == CHAR_NULL || DestPath[StrLen(Node->FullName)] == L'\\') ) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_SD_SAME), gShellLevel2HiiHandle, L"cp"); ShellStatus = SHELL_INVALID_PARAMETER; break; } PathCleanUpDirectories(DestPath); if (!SilentMode) { ShellPrintEx(-1, -1, HiiOutput, Node->FullName, DestPath); } // // copy single file... // ShellStatus = CopySingleFile(Node->FullName, DestPath, &Response, SilentMode, L"cp"); if (ShellStatus != SHELL_SUCCESS) { break; } } if (ShellStatus == SHELL_SUCCESS && Resp == NULL) { ShellPrintEx(-1, -1, L"%s", HiiResultOk); } SHELL_FREE_NON_NULL(DestPath); SHELL_FREE_NON_NULL(HiiOutput); SHELL_FREE_NON_NULL(HiiResultOk); SHELL_FREE_NON_NULL(CleanFilePathStr); if (Resp == NULL) { SHELL_FREE_NON_NULL(Response); } return (ShellStatus); }
/** function to take a list of files to move and a destination location and do the verification and moving of those files to that location. This function will report any errors to the user and continue to move the rest of the files. @param[in] FileList A LIST_ENTRY* based list of files to move @param[out] Resp pointer to response from question. Pass back on looped calling @param[in] DestParameter the originally specified destination location @retval SHELL_SUCCESS the files were all moved. @retval SHELL_INVALID_PARAMETER a parameter was invalid @retval SHELL_SECURITY_VIOLATION a security violation ocurred @retval SHELL_WRITE_PROTECTED the destination was write protected @retval SHELL_OUT_OF_RESOURCES a memory allocation failed **/ SHELL_STATUS EFIAPI ValidateAndMoveFiles( IN EFI_SHELL_FILE_INFO *FileList, OUT VOID **Resp, IN CONST CHAR16 *DestParameter ) { EFI_STATUS Status; CHAR16 *HiiOutput; CHAR16 *HiiResultOk; CHAR16 *DestPath; CHAR16 *FullDestPath; CONST CHAR16 *Cwd; CHAR16 *FullCwd; SHELL_STATUS ShellStatus; EFI_SHELL_FILE_INFO *Node; VOID *Response; UINT64 Attr; CHAR16 *CleanFilePathStr; ASSERT(FileList != NULL); ASSERT(DestParameter != NULL); DestPath = NULL; FullDestPath = NULL; Cwd = ShellGetCurrentDir(NULL); Response = *Resp; Attr = 0; CleanFilePathStr = NULL; FullCwd = NULL; if (Cwd != NULL) { FullCwd = AllocateZeroPool(StrSize(Cwd) + sizeof(CHAR16)); if (FullCwd == NULL) { return SHELL_OUT_OF_RESOURCES; } else { StrCpyS(FullCwd, StrSize(Cwd)/sizeof(CHAR16)+1, Cwd); StrCatS(FullCwd, StrSize(Cwd)/sizeof(CHAR16)+1, L"\\"); } } Status = ShellLevel2StripQuotes (DestParameter, &CleanFilePathStr); if (EFI_ERROR (Status)) { SHELL_FREE_NON_NULL(FullCwd); if (Status == EFI_OUT_OF_RESOURCES) { return SHELL_OUT_OF_RESOURCES; } else { return SHELL_INVALID_PARAMETER; } } ASSERT (CleanFilePathStr != NULL); // // Get and validate the destination location // ShellStatus = GetDestinationLocation(CleanFilePathStr, &DestPath, FullCwd, (BOOLEAN)(FileList->Link.ForwardLink == FileList->Link.BackLink), &Attr); FreePool (CleanFilePathStr); if (ShellStatus != SHELL_SUCCESS) { SHELL_FREE_NON_NULL (FullCwd); return (ShellStatus); } DestPath = PathCleanUpDirectories(DestPath); if (DestPath == NULL) { FreePool (FullCwd); return (SHELL_OUT_OF_RESOURCES); } HiiOutput = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_MV_OUTPUT), NULL); HiiResultOk = HiiGetString (gShellLevel2HiiHandle, STRING_TOKEN (STR_GEN_RES_OK), NULL); if (HiiOutput == NULL || HiiResultOk == NULL) { SHELL_FREE_NON_NULL(DestPath); SHELL_FREE_NON_NULL(HiiOutput); SHELL_FREE_NON_NULL(HiiResultOk); SHELL_FREE_NON_NULL(FullCwd); return (SHELL_OUT_OF_RESOURCES); } // // Go through the list of files and directories to move... // for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link) ; !IsNull(&FileList->Link, &Node->Link) ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&FileList->Link, &Node->Link) ){ if (ShellGetExecutionBreakFlag()) { break; } // // These should never be NULL // ASSERT(Node->FileName != NULL); ASSERT(Node->FullName != NULL); ASSERT(Node->Info != NULL); // // skip the directory traversing stuff... // if (StrCmp(Node->FileName, L".") == 0 || StrCmp(Node->FileName, L"..") == 0) { continue; } SHELL_FREE_NON_NULL(FullDestPath); FullDestPath = NULL; if (ShellIsDirectory(DestPath)==EFI_SUCCESS) { CreateFullDestPath((CONST CHAR16 **)&DestPath, &FullDestPath, Node->FileName); } // // Validate that the move is valid // if (!IsValidMove(Node->FullName, FullCwd, FullDestPath!=NULL? FullDestPath:DestPath, Node->Info->Attribute, Attr, Node->Status)) { ShellStatus = SHELL_INVALID_PARAMETER; continue; } ShellPrintEx(-1, -1, HiiOutput, Node->FullName, FullDestPath!=NULL? FullDestPath:DestPath); // // See if destination exists // if (!EFI_ERROR(ShellFileExists(FullDestPath!=NULL? FullDestPath:DestPath))) { if (Response == NULL) { ShellPromptForResponseHii(ShellPromptResponseTypeYesNoAllCancel, STRING_TOKEN (STR_GEN_DEST_EXIST_OVR), gShellLevel2HiiHandle, &Response); } switch (*(SHELL_PROMPT_RESPONSE*)Response) { case ShellPromptResponseNo: FreePool(Response); Response = NULL; continue; case ShellPromptResponseCancel: *Resp = Response; // // indicate to stop everything // SHELL_FREE_NON_NULL(FullCwd); return (SHELL_ABORTED); case ShellPromptResponseAll: *Resp = Response; break; case ShellPromptResponseYes: FreePool(Response); Response = NULL; break; default: FreePool(Response); SHELL_FREE_NON_NULL(FullCwd); return SHELL_ABORTED; } Status = ShellDeleteFileByName(FullDestPath!=NULL? FullDestPath:DestPath); } if (IsBetweenFileSystem(Node->FullName, FullCwd, DestPath)) { while (FullDestPath == NULL && DestPath != NULL && DestPath[0] != CHAR_NULL && DestPath[StrLen(DestPath) - 1] == L'\\') { DestPath[StrLen(DestPath) - 1] = CHAR_NULL; } Status = MoveBetweenFileSystems(Node, FullDestPath!=NULL? FullDestPath:DestPath, &Response); } else { Status = MoveWithinFileSystems(Node, DestPath, &Response); // // Display error status // if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_UK), gShellLevel2HiiHandle, L"mv", Status); } } // // Check our result // if (EFI_ERROR(Status)) { ShellStatus = SHELL_INVALID_PARAMETER; if (Status == EFI_SECURITY_VIOLATION) { ShellStatus = SHELL_SECURITY_VIOLATION; } else if (Status == EFI_WRITE_PROTECTED) { ShellStatus = SHELL_WRITE_PROTECTED; } else if (Status == EFI_OUT_OF_RESOURCES) { ShellStatus = SHELL_OUT_OF_RESOURCES; } else if (Status == EFI_DEVICE_ERROR) { ShellStatus = SHELL_DEVICE_ERROR; } else if (Status == EFI_ACCESS_DENIED) { ShellStatus = SHELL_ACCESS_DENIED; } } else { ShellPrintEx(-1, -1, L"%s", HiiResultOk); } } // main for loop SHELL_FREE_NON_NULL(FullDestPath); SHELL_FREE_NON_NULL(DestPath); SHELL_FREE_NON_NULL(HiiOutput); SHELL_FREE_NON_NULL(HiiResultOk); SHELL_FREE_NON_NULL(FullCwd); return (ShellStatus); }
/** Function for 'cp' 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 ShellCommandRunCp ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; UINTN ParamCount; UINTN LoopCounter; EFI_SHELL_FILE_INFO *FileList; BOOLEAN SilentMode; BOOLEAN RecursiveMode; CONST CHAR16 *Cwd; CHAR16 *FullCwd; ProblemParam = NULL; ShellStatus = SHELL_SUCCESS; ParamCount = 0; FileList = 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 (ParamList, &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"cp", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { // // check for "-?" // if (ShellCommandLineGetFlag(Package, L"-?")) { ASSERT(FALSE); } // // Initialize SilentMode and RecursiveMode // if (gEfiShellProtocol->BatchIsActive()) { SilentMode = TRUE; } else { SilentMode = ShellCommandLineGetFlag(Package, L"-q"); } RecursiveMode = ShellCommandLineGetFlag(Package, L"-r"); switch (ParamCount = ShellCommandLineGetCount(Package)) { case 0: case 1: // // we have insufficient parameters // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"cp"); ShellStatus = SHELL_INVALID_PARAMETER; break; case 2: // // must have valid CWD for single parameter... // Cwd = ShellGetCurrentDir(NULL); if (Cwd == NULL){ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"cp"); ShellStatus = SHELL_INVALID_PARAMETER; } else { Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, 1), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); if (FileList == NULL || IsListEmpty(&FileList->Link) || EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue(Package, 1)); ShellStatus = SHELL_NOT_FOUND; } else { FullCwd = AllocateZeroPool(StrSize(Cwd) + sizeof(CHAR16)); if (FullCwd == NULL) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellLevel2HiiHandle, L"cp"); ShellStatus = SHELL_OUT_OF_RESOURCES; } else { StrCpyS (FullCwd, StrSize (Cwd) / sizeof (CHAR16) + 1, Cwd); ShellStatus = ProcessValidateAndCopyFiles (FileList, FullCwd, SilentMode, RecursiveMode); FreePool (FullCwd); } } } break; default: // // Make a big list of all the files... // for (ParamCount--, LoopCounter = 1 ; LoopCounter < ParamCount && ShellStatus == SHELL_SUCCESS ; LoopCounter++) { if (ShellGetExecutionBreakFlag()) { break; } Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, LoopCounter), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); if (EFI_ERROR(Status) || FileList == NULL || IsListEmpty(&FileList->Link)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue(Package, LoopCounter)); ShellStatus = SHELL_NOT_FOUND; } } if (ShellStatus != SHELL_SUCCESS) { Status = ShellCloseFileMetaArg(&FileList); } else { // // now copy them all... // if (FileList != NULL && !IsListEmpty(&FileList->Link)) { ShellStatus = ProcessValidateAndCopyFiles(FileList, PathCleanUpDirectories((CHAR16*)ShellCommandLineGetRawValue(Package, ParamCount)), SilentMode, RecursiveMode); Status = ShellCloseFileMetaArg(&FileList); if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, L"cp", ShellCommandLineGetRawValue(Package, ParamCount), ShellStatus|MAX_BIT); ShellStatus = SHELL_ACCESS_DENIED; } } } break; } // switch on parameter count if (FileList != NULL) { ShellCloseFileMetaArg(&FileList); } // // free the command line package // ShellCommandLineFreeVarList (Package); } if (ShellGetExecutionBreakFlag()) { return (SHELL_ABORTED); } return (ShellStatus); }
/** Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended consumption, the firmware may process the capsule immediately. If the payload should persist across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must be passed into ResetSystem() and will cause the capsule to be processed by the firmware as part of the reset process. @param CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules being passed into update capsule. @param CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in CaspuleHeaderArray. @param ScatterGatherList Physical pointer to a set of EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the location in physical memory of a set of capsules. @retval EFI_SUCCESS Valid capsule was passed. If CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the capsule has been successfully processed by the firmware. @retval EFI_DEVICE_ERROR The capsule update was started, but failed due to a device error. @retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible set of flags were set in the capsule header. @retval EFI_INVALID_PARAMETER CapsuleCount is Zero. @retval EFI_INVALID_PARAMETER For across reset capsule image, ScatterGatherList is NULL. @retval EFI_UNSUPPORTED CapsuleImage is not recognized by the firmware. @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule is compatible with this platform but is not capable of being submitted or processed in runtime. The caller may resubmit the capsule prior to ExitBootServices(). @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates the capsule is compatible with this platform but there are insufficient resources to process. **/ EFI_STATUS EFIAPI UpdateCapsule ( IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, IN UINTN CapsuleCount, IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL ) { UINTN ArrayNumber; EFI_STATUS Status; EFI_CAPSULE_HEADER *CapsuleHeader; BOOLEAN NeedReset; BOOLEAN InitiateReset; CHAR16 CapsuleVarName[30]; CHAR16 *TempVarName; // // Capsule Count can't be less than one. // if (CapsuleCount < 1) { return EFI_INVALID_PARAMETER; } NeedReset = FALSE; InitiateReset = FALSE; CapsuleHeader = NULL; CapsuleVarName[0] = 0; for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) { // // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag must have // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well. // CapsuleHeader = CapsuleHeaderArray[ArrayNumber]; if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) { return EFI_INVALID_PARAMETER; } // // A capsule which has the CAPSULE_FLAGS_INITIATE_RESET flag must have // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well. // if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) { return EFI_INVALID_PARAMETER; } // // Check FMP capsule flag // if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid) && (CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0 ) { return EFI_INVALID_PARAMETER; } // // Check Capsule image without populate flag by firmware support capsule function // if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) { Status = SupportCapsuleImage (CapsuleHeader); if (EFI_ERROR(Status)) { return Status; } } } // // Walk through all capsules, record whether there is a capsule needs reset // or initiate reset. And then process capsules which has no reset flag directly. // for (ArrayNumber = 0; ArrayNumber < CapsuleCount ; ArrayNumber++) { CapsuleHeader = CapsuleHeaderArray[ArrayNumber]; // // Here should be in the boot-time for non-reset capsule image // Platform specific update for the non-reset capsule image. // if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) == 0) { if (EfiAtRuntime ()) { Status = EFI_OUT_OF_RESOURCES; } else { Status = ProcessCapsuleImage(CapsuleHeader); } if (EFI_ERROR(Status)) { return Status; } } else { NeedReset = TRUE; if ((CapsuleHeader->Flags & CAPSULE_FLAGS_INITIATE_RESET) != 0) { InitiateReset = TRUE; } } } // // After launching all capsules who has no reset flag, if no more capsules claims // for a system reset just return. // if (!NeedReset) { return EFI_SUCCESS; } // // ScatterGatherList is only referenced if the capsules are defined to persist across // system reset. // if (ScatterGatherList == (EFI_PHYSICAL_ADDRESS) (UINTN) NULL) { return EFI_INVALID_PARAMETER; } // // Check if the platform supports update capsule across a system reset // if (!IsPersistAcrossResetCapsuleSupported ()) { return EFI_UNSUPPORTED; } CapsuleCacheWriteBack (ScatterGatherList); // // Construct variable name CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2... // if user calls UpdateCapsule multiple times. // StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CHAR16), EFI_CAPSULE_VARIABLE_NAME); TempVarName = CapsuleVarName + StrLen (CapsuleVarName); if (mTimes > 0) { UnicodeValueToStringS ( TempVarName, sizeof (CapsuleVarName) - ((UINTN)TempVarName - (UINTN)CapsuleVarName), 0, mTimes, 0 ); } // // ScatterGatherList is only referenced if the capsules are defined to persist across // system reset. Set its value into NV storage to let pre-boot driver to pick it up // after coming through a system reset. // Status = EfiSetVariable ( CapsuleVarName, &gEfiCapsuleVendorGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, sizeof (UINTN), (VOID *) &ScatterGatherList ); if (!EFI_ERROR (Status)) { // // Variable has been set successfully, increase variable index. // mTimes++; if(InitiateReset) { // // Firmware that encounters a capsule which has the CAPSULE_FLAGS_INITIATE_RESET Flag set in its header // will initiate a reset of the platform which is compatible with the passed-in capsule request and will // not return back to the caller. // EfiResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); } } return Status; }
/** Get devcie name through the component name protocol. @param[in] AllHandlesBuffer The handle buffer for current system. @param[in] NumAllHandles The number of handles for the handle buffer. @param[in] Dev The device which need to get name. @param[in] UseComp1 Whether use component name or name2 protocol. @retval TRUE Find the name for this device. @retval FALSE Not found the name for this device. **/ BOOLEAN OpalDriverGetDeviceNameByProtocol( EFI_HANDLE *AllHandlesBuffer, UINTN NumAllHandles, OPAL_DRIVER_DEVICE *Dev, BOOLEAN UseComp1 ) { EFI_HANDLE* ProtocolHandlesBuffer; UINTN NumProtocolHandles; EFI_STATUS Status; EFI_COMPONENT_NAME2_PROTOCOL* Cnp1_2; // efi component name and componentName2 have same layout EFI_GUID Protocol; UINTN StrLength; EFI_DEVICE_PATH_PROTOCOL* TmpDevPath; UINTN Index1; UINTN Index2; EFI_HANDLE TmpHandle; CHAR16 *DevName; if (Dev == NULL || AllHandlesBuffer == NULL || NumAllHandles == 0) { return FALSE; } Protocol = UseComp1 ? gEfiComponentNameProtocolGuid : gEfiComponentName2ProtocolGuid; // // Find all EFI_HANDLES with protocol // Status = gBS->LocateHandleBuffer( ByProtocol, &Protocol, NULL, &NumProtocolHandles, &ProtocolHandlesBuffer ); if (EFI_ERROR(Status)) { return FALSE; } // // Exit early if no supported devices // if (NumProtocolHandles == 0) { return FALSE; } // // Get printable name by iterating through all protocols // using the handle as the child, and iterate through all handles for the controller // exit loop early once found, if not found, then delete device // storage security protocol instances already exist, add them to internal list // Status = EFI_DEVICE_ERROR; for (Index1 = 0; Index1 < NumProtocolHandles; Index1++) { DevName = NULL; if (Dev->Name16 != NULL) { return TRUE; } TmpHandle = ProtocolHandlesBuffer[Index1]; Status = gBS->OpenProtocol( TmpHandle, &Protocol, (VOID**)&Cnp1_2, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR(Status) || Cnp1_2 == NULL) { continue; } // // Use all handles array as controller handle // for (Index2 = 0; Index2 < NumAllHandles; Index2++) { Status = Cnp1_2->GetControllerName( Cnp1_2, AllHandlesBuffer[Index2], Dev->Handle, LANGUAGE_ISO_639_2_ENGLISH, &DevName ); if (EFI_ERROR(Status)) { Status = Cnp1_2->GetControllerName( Cnp1_2, AllHandlesBuffer[Index2], Dev->Handle, LANGUAGE_RFC_3066_ENGLISH, &DevName ); } if (!EFI_ERROR(Status) && DevName != NULL) { StrLength = StrLen(DevName) + 1; // Add one for NULL terminator Dev->Name16 = AllocateZeroPool(StrLength * sizeof (CHAR16)); ASSERT (Dev->Name16 != NULL); StrCpyS (Dev->Name16, StrLength, DevName); Dev->NameZ = (CHAR8*)AllocateZeroPool(StrLength); UnicodeStrToAsciiStrS (DevName, Dev->NameZ, StrLength); // // Retrieve bridge BDF info and port number or namespace depending on type // TmpDevPath = NULL; Status = gBS->OpenProtocol( Dev->Handle, &gEfiDevicePathProtocolGuid, (VOID**)&TmpDevPath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (!EFI_ERROR(Status)) { Dev->OpalDevicePath = DuplicateDevicePath (TmpDevPath); return TRUE; } if (Dev->Name16 != NULL) { FreePool(Dev->Name16); Dev->Name16 = NULL; } if (Dev->NameZ != NULL) { FreePool(Dev->NameZ); Dev->NameZ = NULL; } } } } return FALSE; }
/** Function to do a move within a file system. @param[in] Node A pointer to the file to be removed. @param[in] DestPath A pointer to the destination file path. @param[out] Resp A pointer to response from question. Pass back on looped calling. @retval SHELL_SUCCESS The source file was moved to the destination. @retval SHELL_OUT_OF_RESOURCES A memory allocation failed. **/ EFI_STATUS EFIAPI MoveWithinFileSystems( IN EFI_SHELL_FILE_INFO *Node, IN CHAR16 *DestPath, OUT VOID **Resp ) { EFI_FILE_INFO *NewFileInfo; CHAR16 *TempLocation; UINTN NewSize; UINTN Length; EFI_STATUS Status; // // Chop off map info from DestPath // if ((TempLocation = StrStr(DestPath, L":")) != NULL) { CopyMem(DestPath, TempLocation+1, StrSize(TempLocation+1)); } // // construct the new file info block // NewSize = StrSize(DestPath); NewSize += StrSize(Node->FileName) + SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16); NewFileInfo = AllocateZeroPool(NewSize); if (NewFileInfo == NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellLevel2HiiHandle); Status = EFI_OUT_OF_RESOURCES; } else { CopyMem(NewFileInfo, Node->Info, SIZE_OF_EFI_FILE_INFO); if (DestPath[0] != L'\\') { StrCpyS(NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof(CHAR16), L"\\"); StrCatS(NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof(CHAR16), DestPath); } else { StrCpyS(NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof(CHAR16), DestPath); } Length = StrLen(NewFileInfo->FileName); if (Length > 0) { Length--; } if (NewFileInfo->FileName[Length] == L'\\') { if (Node->FileName[0] == L'\\') { // // Don't allow for double slashes. Eliminate one of them. // NewFileInfo->FileName[Length] = CHAR_NULL; } StrCatS(NewFileInfo->FileName, (NewSize - SIZE_OF_EFI_FILE_INFO) / sizeof(CHAR16), Node->FileName); } NewFileInfo->Size = SIZE_OF_EFI_FILE_INFO + StrSize(NewFileInfo->FileName); // // Perform the move operation // Status = ShellSetFileInfo(Node->Handle, NewFileInfo); // // Free the info object we used... // FreePool(NewFileInfo); } return (Status); }
/** Dump capsule status variable. @retval EFI_SUCCESS The capsule status variable is dumped. @retval EFI_UNSUPPORTED Input parameter is not valid. **/ EFI_STATUS DmpCapsuleStatusVariable ( VOID ) { EFI_STATUS Status; UINT32 Index; CHAR16 CapsuleVarName[20]; CHAR16 *TempVarName; EFI_CAPSULE_RESULT_VARIABLE_HEADER *CapsuleResult; EFI_CAPSULE_RESULT_VARIABLE_FMP *CapsuleResultFmp; UINTN CapsuleFileNameSize; CHAR16 CapsuleIndexData[12]; CHAR16 *CapsuleIndex; Status = GetVariable2( L"CapsuleMax", &gEfiCapsuleReportGuid, (VOID **)&CapsuleIndex, NULL ); if (!EFI_ERROR(Status)) { CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16)); CapsuleIndexData[11] = 0; Print(L"CapsuleMax - %s\n", CapsuleIndexData); FreePool(CapsuleIndex); } Status = GetVariable2( L"CapsuleLast", &gEfiCapsuleReportGuid, (VOID **)&CapsuleIndex, NULL ); if (!EFI_ERROR(Status)) { CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16)); CapsuleIndexData[11] = 0; Print(L"CapsuleLast - %s\n", CapsuleIndexData); FreePool(CapsuleIndex); } StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CapsuleVarName[0]), L"Capsule"); TempVarName = CapsuleVarName + StrLen (CapsuleVarName); Index = 0; while (TRUE) { UnicodeSPrint (TempVarName, 5 * sizeof(CHAR16), L"%04x", Index); Status = GetVariable2 ( CapsuleVarName, &gEfiCapsuleReportGuid, (VOID **) &CapsuleResult, NULL ); if (Status == EFI_NOT_FOUND) { break; } else if (EFI_ERROR(Status)) { continue; } ASSERT (CapsuleResult != NULL); // // display capsule process status // if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER)) { Print (L"CapsuleName: %s\n", CapsuleVarName); Print (L" Capsule Guid: %g\n", &CapsuleResult->CapsuleGuid); Print (L" Capsule ProcessedTime: %t\n", &CapsuleResult->CapsuleProcessed); Print (L" Capsule Status: %r\n", CapsuleResult->CapsuleStatus); } if (CompareGuid(&CapsuleResult->CapsuleGuid, &gEfiFmpCapsuleGuid)) { if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP)) { CapsuleResultFmp = (EFI_CAPSULE_RESULT_VARIABLE_FMP *)(CapsuleResult + 1); Print(L" Capsule FMP Version: 0x%x\n", CapsuleResultFmp->Version); Print(L" Capsule FMP PayloadIndex: 0x%x\n", CapsuleResultFmp->PayloadIndex); Print(L" Capsule FMP UpdateImageIndex: 0x%x\n", CapsuleResultFmp->UpdateImageIndex); Print(L" Capsule FMP UpdateImageTypeId: %g\n", &CapsuleResultFmp->UpdateImageTypeId); if (CapsuleResult->VariableTotalSize > sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP)) { Print(L" Capsule FMP CapsuleFileName: %s\n", (CapsuleResultFmp + 1)); CapsuleFileNameSize = StrSize((CHAR16 *)(CapsuleResultFmp + 1)); if (CapsuleResult->VariableTotalSize > sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP) + CapsuleFileNameSize) { Print(L" Capsule FMP CapsuleTarget: %s\n", (UINT8 *)(CapsuleResultFmp + 1) + CapsuleFileNameSize); } } } } FreePool(CapsuleResult); Index++; if (Index > 0xFFFF) { break; } } return EFI_SUCCESS; }
/** Function for 'mv' 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 ShellCommandRunMv ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; CHAR16 *Cwd; UINTN CwdSize; SHELL_STATUS ShellStatus; UINTN ParamCount; UINTN LoopCounter; EFI_SHELL_FILE_INFO *FileList; VOID *Response; ProblemParam = NULL; ShellStatus = SHELL_SUCCESS; ParamCount = 0; FileList = NULL; Response = NULL; // // 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"mv", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { // // check for "-?" // if (ShellCommandLineGetFlag(Package, L"-?")) { ASSERT(FALSE); } switch (ParamCount = ShellCommandLineGetCount(Package)) { case 0: case 1: // // we have insufficient parameters // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"mv"); ShellStatus = SHELL_INVALID_PARAMETER; break; case 2: // // must have valid CWD for single parameter... // if (ShellGetCurrentDir(NULL) == NULL){ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle, L"mv"); ShellStatus = SHELL_INVALID_PARAMETER; } else { Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, 1), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); if (FileList == NULL || IsListEmpty(&FileList->Link) || EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"mv", ShellCommandLineGetRawValue(Package, 1)); ShellStatus = SHELL_NOT_FOUND; } else { // // ValidateAndMoveFiles will report errors to the screen itself // CwdSize = StrSize(ShellGetCurrentDir(NULL)) + sizeof(CHAR16); Cwd = AllocateZeroPool(CwdSize); ASSERT (Cwd != NULL); StrCpyS(Cwd, CwdSize/sizeof(CHAR16), ShellGetCurrentDir(NULL)); StrCatS(Cwd, CwdSize/sizeof(CHAR16), L"\\"); ShellStatus = ValidateAndMoveFiles(FileList, &Response, Cwd); FreePool(Cwd); } } break; default: ///@todo make sure this works with error half way through and continues... for (ParamCount--, LoopCounter = 1 ; LoopCounter < ParamCount ; LoopCounter++) { if (ShellGetExecutionBreakFlag()) { break; } Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, LoopCounter), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); if (FileList == NULL || IsListEmpty(&FileList->Link) || EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"mv", ShellCommandLineGetRawValue(Package, LoopCounter)); ShellStatus = SHELL_NOT_FOUND; } else { // // ValidateAndMoveFiles will report errors to the screen itself // Only change ShellStatus if it's sucessful // if (ShellStatus == SHELL_SUCCESS) { ShellStatus = ValidateAndMoveFiles(FileList, &Response, ShellCommandLineGetRawValue(Package, ParamCount)); } else { ValidateAndMoveFiles(FileList, &Response, ShellCommandLineGetRawValue(Package, ParamCount)); } } if (FileList != NULL && !IsListEmpty(&FileList->Link)) { Status = ShellCloseFileMetaArg(&FileList); if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) { ShellStatus = SHELL_ACCESS_DENIED; ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, L"mv", ShellCommandLineGetRawValue(Package, 1), ShellStatus|MAX_BIT); } } } break; } // switch on parameter count if (FileList != NULL) { ShellCloseFileMetaArg(&FileList); } // // free the command line package // ShellCommandLineFreeVarList (Package); } SHELL_FREE_NON_NULL(Response); if (ShellGetExecutionBreakFlag()) { return (SHELL_ABORTED); } return (ShellStatus); }
/** Update the progress of a file download This procedure is called each time a new TFTP packet is received. @param[in] This MTFTP4 protocol interface @param[in] Token Parameters for the download of the file @param[in] PacketLen Length of the packet @param[in] Packet Address of the packet @retval EFI_SUCCESS All packets are accepted. **/ STATIC EFI_STATUS EFIAPI CheckPacket ( IN EFI_MTFTP4_PROTOCOL *This, IN EFI_MTFTP4_TOKEN *Token, IN UINT16 PacketLen, IN EFI_MTFTP4_PACKET *Packet ) { DOWNLOAD_CONTEXT *Context; CHAR16 Progress[TFTP_PROGRESS_MESSAGE_SIZE]; UINTN NbOfKb; UINTN Index; UINTN LastStep; UINTN Step; EFI_STATUS Status; if ((NTOHS (Packet->OpCode)) != EFI_MTFTP4_OPCODE_DATA) { return EFI_SUCCESS; } Context = (DOWNLOAD_CONTEXT*)Token->Context; if (Context->DownloadedNbOfBytes == 0) { ShellPrintEx (-1, -1, L"%s 0 Kb", mTftpProgressFrame); } // // The data in the packet are prepended with two UINT16 : // . OpCode = EFI_MTFTP4_OPCODE_DATA // . Block = the number of this block of data // Context->DownloadedNbOfBytes += PacketLen - sizeof (Packet->OpCode) - sizeof (Packet->Data.Block); NbOfKb = Context->DownloadedNbOfBytes / 1024; Progress[0] = L'\0'; LastStep = (Context->LastReportedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize; Step = (Context->DownloadedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize; if (Step <= LastStep) { return EFI_SUCCESS; } ShellPrintEx (-1, -1, L"%s", mTftpProgressDelete); Status = StrCpyS (Progress, TFTP_PROGRESS_MESSAGE_SIZE, mTftpProgressFrame); if (EFI_ERROR(Status)) { return Status; } for (Index = 1; Index < Step; Index++) { Progress[Index] = L'='; } Progress[Step] = L'>'; UnicodeSPrint ( Progress + (sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 1, sizeof (Progress) - sizeof (mTftpProgressFrame), L" %7d Kb", NbOfKb ); Context->LastReportedNbOfBytes = Context->DownloadedNbOfBytes; ShellPrintEx (-1, -1, L"%s", Progress); return EFI_SUCCESS; }