/** Set the name of a file. This is a helper function for SetFileInfo(). @param[in] Instance A pointer to the description of the volume the file belongs to. @param[in] File A pointer to the description of the file. @param[in] FileName A pointer to the new name of the file. @retval EFI_SUCCESS The name was set. @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file to a file that is already present. **/ STATIC EFI_STATUS SetFileName ( IN BOOTMON_FS_INSTANCE *Instance, IN BOOTMON_FS_FILE *File, IN CONST CHAR16 *FileName ) { CHAR8 AsciiFileName[MAX_NAME_LENGTH]; BOOTMON_FS_FILE *SameFile; // If the file path start with a \ strip it. The EFI Shell may // insert a \ in front of the file name. if (FileName[0] == L'\\') { FileName++; } UnicodeStrToAsciiStrS (FileName, AsciiFileName, MAX_NAME_LENGTH); if (BootMonGetFileFromAsciiFileName ( File->Instance, AsciiFileName, &SameFile ) != EFI_NOT_FOUND) { // A file with that name already exists. return EFI_ACCESS_DENIED; } else { // OK, change the filename. AsciiStrToUnicodeStrS (AsciiFileName, File->Info->FileName, (File->Info->Size - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16)); return EFI_SUCCESS; } }
/** 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] ImageStruct Point to the image structure. @return The resulting Ascii name string is stored in the mNameString global array. **/ CHAR8 * GetDriverNameString ( IN SMM_CORE_IMAGE_DATABASE_STRUCTURE *ImageStruct ) { EFI_STATUS Status; CHAR16 *NameString; UINTN StringSize; if (ImageStruct == NULL) { return "???"; } // // Method 1: Get the name string from image PDB // if (ImageStruct->PdbStringOffset != 0) { GetShortPdbFileName ((CHAR8 *) ((UINTN) ImageStruct + ImageStruct->PdbStringOffset), mNameString); return mNameString; } if (!IsZeroGuid (&ImageStruct->FileGuid)) { // // Try to get the image's FFS UI section by image GUID // NameString = NULL; StringSize = 0; Status = GetSectionFromAnyFv ( &ImageStruct->FileGuid, EFI_SECTION_USER_INTERFACE, 0, (VOID **) &NameString, &StringSize ); if (!EFI_ERROR (Status)) { // // Method 2: Get the name string from FFS UI section // if (StrLen (NameString) > PROFILE_NAME_STRING_LENGTH) { NameString[PROFILE_NAME_STRING_LENGTH] = 0; } UnicodeStrToAsciiStrS (NameString, mNameString, sizeof (mNameString)); FreePool (NameString); return mNameString; } } // // Method 3: Get the name string from image GUID // AsciiSPrint (mNameString, sizeof (mNameString), "%g", &ImageStruct->FileGuid); return mNameString; }
CHAR8* Unicode2Ascii ( CONST CHAR16* UnicodeStr ) { UINTN BufSize = StrSize (UnicodeStr) * sizeof (CHAR8); CHAR8* AsciiStr = AllocatePool(BufSize); if (AsciiStr == NULL) { return NULL; } UnicodeStrToAsciiStrS(UnicodeStr, AsciiStr, BufSize); return AsciiStr; }
/** Embedded Boot Loader (EBL) - A simple EFI command line application for embedded devices. PcdEmbeddedAutomaticBootCommand is a complied in command line that gets executed automatically. The ; separator allows multiple commands for each command line. @param ImageHandle EFI ImageHandle for this application. @param SystemTable EFI system table @return EFI status of the application **/ EFI_STATUS EFIAPI EdkBootLoaderEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; CHAR8 CmdLine[MAX_CMD_LINE]; CHAR16 *CommandLineVariable = NULL; CHAR16 *CommandLineVariableName = L"default-cmdline"; UINTN CommandLineVariableSize = 0; EFI_GUID VendorGuid; // Initialize tables of commands EblInitializeCmdTable (); EblInitializeDeviceCmd (); EblInitializemdHwDebugCmds (); EblInitializemdHwIoDebugCmds (); EblInitializeDirCmd (); EblInitializeHobCmd (); EblInitializeScriptCmd (); EblInitializeExternalCmd (); EblInitializeNetworkCmd(); EblInitializeVariableCmds (); if (gST->ConOut == NULL) { DEBUG((EFI_D_ERROR,"Error: No Console Output\n")); return EFI_NOT_READY; } // Disable the 5 minute EFI watchdog time so we don't get automatically reset gBS->SetWatchdogTimer (0, 0, 0, NULL); if (FeaturePcdGet (PcdEmbeddedMacBoot)) { // A MAC will boot in graphics mode, so turn it back to text here // This protocol was removed from edk2. It is only an edk thing. We need to make our own copy. // DisableQuietBoot (); // Enable the biggest output screen size possible gST->ConOut->SetMode (gST->ConOut, (UINTN)gST->ConOut->Mode->MaxMode - 1); } // Save current screen mode gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &gScreenColumns, &gScreenRows); EblPrintStartupBanner (); // Parse command line and handle commands separated by ; // The loop prints the prompt gets user input and saves history // Look for a variable with a default command line, otherwise use the Pcd ZeroMem(&VendorGuid, sizeof(EFI_GUID)); Status = gRT->GetVariable(CommandLineVariableName, &VendorGuid, NULL, &CommandLineVariableSize, CommandLineVariable); if (Status == EFI_BUFFER_TOO_SMALL) { CommandLineVariable = AllocatePool(CommandLineVariableSize); Status = gRT->GetVariable(CommandLineVariableName, &VendorGuid, NULL, &CommandLineVariableSize, CommandLineVariable); if (!EFI_ERROR(Status)) { UnicodeStrToAsciiStrS (CommandLineVariable, CmdLine, MAX_CMD_LINE); } FreePool(CommandLineVariable); } if (EFI_ERROR(Status)) { AsciiStrCpyS (CmdLine, MAX_CMD_LINE, (CHAR8 *)PcdGetPtr (PcdEmbeddedAutomaticBootCommand)); } for (;;) { Status = ProcessCmdLine (CmdLine, MAX_CMD_LINE); if (Status == EFI_ABORTED) { // if a command returns EFI_ABORTED then exit the EBL EblShutdownExternalCmdTable (); return EFI_SUCCESS; } // get the command line from the user EblPrompt (); GetCmd (CmdLine, MAX_CMD_LINE); SetCmdHistory (CmdLine); if (FeaturePcdGet (PcdEmbeddedProbeRemovable)) { // Probe removable media devices to see if media has been inserted or removed. EblProbeRemovableMedia (); } } }
/** Function to write a line of text to a file. If the file is a Unicode file (with UNICODE file tag) then write the unicode text. If the file is an ASCII file then write the ASCII text. If the size of file is zero (without file tag at the beginning) then write ASCII text as default. @param[in] Handle FileHandle to write to. @param[in] Buffer Buffer to write, if NULL the function will take no action and return EFI_SUCCESS. @retval EFI_SUCCESS The data was written. Buffer is NULL. @retval EFI_INVALID_PARAMETER Handle is NULL. @retval EFI_OUT_OF_RESOURCES Unable to allocate temporary space for ASCII string due to out of resources. @sa FileHandleWrite **/ EFI_STATUS EFIAPI FileHandleWriteLine( IN EFI_FILE_HANDLE Handle, IN CHAR16 *Buffer ) { EFI_STATUS Status; CHAR16 CharBuffer; UINTN Size; UINTN Index; UINTN CharSize; UINT64 FileSize; UINT64 OriginalFilePosition; BOOLEAN Ascii; CHAR8 *AsciiBuffer; if (Buffer == NULL) { return (EFI_SUCCESS); } if (Handle == NULL) { return (EFI_INVALID_PARAMETER); } Ascii = FALSE; AsciiBuffer = NULL; Status = FileHandleGetPosition(Handle, &OriginalFilePosition); if (EFI_ERROR(Status)) { return Status; } Status = FileHandleSetPosition(Handle, 0); if (EFI_ERROR(Status)) { return Status; } Status = FileHandleGetSize(Handle, &FileSize); if (EFI_ERROR(Status)) { return Status; } if (FileSize == 0) { Ascii = TRUE; } else { CharSize = sizeof (CHAR16); Status = FileHandleRead (Handle, &CharSize, &CharBuffer); ASSERT_EFI_ERROR (Status); if (CharBuffer == gUnicodeFileTag) { Ascii = FALSE; } else { Ascii = TRUE; } } Status = FileHandleSetPosition(Handle, OriginalFilePosition); if (EFI_ERROR(Status)) { return Status; } if (Ascii) { Size = ( StrSize(Buffer) / sizeof(CHAR16) ) * sizeof(CHAR8); AsciiBuffer = (CHAR8 *)AllocateZeroPool(Size); if (AsciiBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStrS (Buffer, AsciiBuffer, Size); for (Index = 0; Index < Size; Index++) { if (!((AsciiBuffer[Index] >= 0) && (AsciiBuffer[Index] < 128))){ FreePool(AsciiBuffer); return EFI_INVALID_PARAMETER; } } Size = AsciiStrSize(AsciiBuffer) - sizeof(CHAR8); Status = FileHandleWrite(Handle, &Size, AsciiBuffer); if (EFI_ERROR(Status)) { FreePool (AsciiBuffer); return (Status); } Size = AsciiStrSize("\r\n") - sizeof(CHAR8); Status = FileHandleWrite(Handle, &Size, "\r\n"); } else { if (OriginalFilePosition == 0) { Status = FileHandleSetPosition (Handle, sizeof(CHAR16)); if (EFI_ERROR(Status)) { return Status; } } Size = StrSize(Buffer) - sizeof(CHAR16); Status = FileHandleWrite(Handle, &Size, Buffer); if (EFI_ERROR(Status)) { return (Status); } Size = StrSize(L"\r\n") - sizeof(CHAR16); Status = FileHandleWrite(Handle, &Size, L"\r\n"); } if (AsciiBuffer != NULL) { FreePool (AsciiBuffer); } 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; }
/** Get password input from the popup windows, and unlock the device. @param[in] Dev The device which need to be unlock. @param[out] PressEsc Whether user escape function through Press ESC. @retval Password string if success. NULL if failed. **/ CHAR8 * OpalDriverPopUpHddPassword ( IN OPAL_DRIVER_DEVICE *Dev, OUT BOOLEAN *PressEsc ) { EFI_INPUT_KEY InputKey; UINTN InputLength; CHAR16 Mask[MAX_PASSWORD_SIZE + 1]; CHAR16 Unicode[MAX_PASSWORD_SIZE + 1]; CHAR8 *Ascii; CHAR16 *PopUpString; UINTN StrLength; ZeroMem(Unicode, sizeof(Unicode)); ZeroMem(Mask, sizeof(Mask)); StrLength = StrLen(Dev->Name16); PopUpString = (CHAR16*) AllocateZeroPool ((8 + StrLength) * 2); *PressEsc = FALSE; if (Dev->Name16 == NULL) { UnicodeSPrint(PopUpString, StrLen(L"Unlock Disk") + 1, L"Unlock Disk"); } else { UnicodeSPrint(PopUpString, StrLen(L"Unlock ") + StrLength + 1, L"Unlock %s", Dev->Name16); } gST->ConOut->ClearScreen(gST->ConOut); InputLength = 0; while (TRUE) { Mask[InputLength] = L'_'; CreatePopUp( EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &InputKey, PopUpString, L"---------------------", Mask, NULL ); // // Check key. // if (InputKey.ScanCode == SCAN_NULL) { // // password finished // if (InputKey.UnicodeChar == CHAR_CARRIAGE_RETURN) { // // Add the null terminator. // Unicode[InputLength] = 0; InputLength++; break; } else if ((InputKey.UnicodeChar == CHAR_NULL) || (InputKey.UnicodeChar == CHAR_TAB) || (InputKey.UnicodeChar == CHAR_LINEFEED) ) { continue; } else { // // delete last key entered // if (InputKey.UnicodeChar == CHAR_BACKSPACE) { if (InputLength > 0) { Unicode[InputLength] = 0; Mask[InputLength] = 0; InputLength--; } } else { // // add Next key entry // Unicode[InputLength] = InputKey.UnicodeChar; Mask[InputLength] = L'*'; InputLength++; if (InputLength == MAX_PASSWORD_SIZE) { // // Add the null terminator. // Unicode[InputLength] = 0; Mask[InputLength] = 0; break; } } } } // // exit on ESC // if (InputKey.ScanCode == SCAN_ESC) { *PressEsc = TRUE; break; } } gST->ConOut->ClearScreen(gST->ConOut); if (InputLength == 0 || InputKey.ScanCode == SCAN_ESC) { return NULL; } Ascii = AllocateZeroPool (MAX_PASSWORD_SIZE + 1); if (Ascii == NULL) { return NULL; } UnicodeStrToAsciiStrS (Unicode, Ascii, MAX_PASSWORD_SIZE + 1); ZeroMem (Unicode, sizeof (Unicode)); return Ascii; }
/** Function for 'tftp' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). @return SHELL_SUCCESS The 'tftp' command completed successfully. @return SHELL_ABORTED The Shell Library initialization failed. @return SHELL_INVALID_PARAMETER At least one of the command's arguments is not valid. @return SHELL_OUT_OF_RESOURCES A memory allocation failed. @return SHELL_NOT_FOUND Network Interface Card not found or server error or file error. **/ SHELL_STATUS EFIAPI ShellCommandRunTftp ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { SHELL_STATUS ShellStatus; EFI_STATUS Status; LIST_ENTRY *CheckPackage; CHAR16 *ProblemParam; UINTN ParamCount; CONST CHAR16 *UserNicName; BOOLEAN NicFound; CONST CHAR16 *ValueStr; CONST CHAR16 *RemoteFilePath; CHAR8 *AsciiRemoteFilePath; UINTN FilePathSize; CONST CHAR16 *Walker; CONST CHAR16 *LocalFilePath; EFI_MTFTP4_CONFIG_DATA Mtftp4ConfigData; EFI_HANDLE *Handles; UINTN HandleCount; UINTN NicNumber; CHAR16 NicName[IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH]; EFI_HANDLE ControllerHandle; EFI_HANDLE Mtftp4ChildHandle; EFI_MTFTP4_PROTOCOL *Mtftp4; UINTN FileSize; VOID *Data; SHELL_FILE_HANDLE FileHandle; UINT16 BlockSize; ShellStatus = SHELL_INVALID_PARAMETER; ProblemParam = NULL; NicFound = FALSE; AsciiRemoteFilePath = NULL; Handles = NULL; FileSize = 0; BlockSize = MTFTP_DEFAULT_BLKSIZE; // // Initialize the Shell library (we must be in non-auto-init...) // Status = ShellInitialize (); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return SHELL_ABORTED; } // // Parse the command line. // Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE); if (EFI_ERROR (Status)) { if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL) ) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellTftpHiiHandle, L"tftp", ProblemParam ); FreePool (ProblemParam); } else { ASSERT (FALSE); } goto Error; } // // Check the number of parameters // ParamCount = ShellCommandLineGetCount (CheckPackage); if (ParamCount > 4) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellTftpHiiHandle, L"tftp" ); goto Error; } if (ParamCount < 3) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellTftpHiiHandle, L"tftp" ); goto Error; } Mtftp4ConfigData = DefaultMtftp4ConfigData; // // Check the host IPv4 address // ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1); Status = NetLibStrToIp4 (ValueStr, &Mtftp4ConfigData.ServerIp); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellTftpHiiHandle, L"tftp", ValueStr ); goto Error; } RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2); ASSERT(RemoteFilePath != NULL); FilePathSize = StrLen (RemoteFilePath) + 1; AsciiRemoteFilePath = AllocatePool (FilePathSize); if (AsciiRemoteFilePath == NULL) { ShellStatus = SHELL_OUT_OF_RESOURCES; goto Error; } UnicodeStrToAsciiStrS (RemoteFilePath, AsciiRemoteFilePath, FilePathSize); if (ParamCount == 4) { LocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3); } else { Walker = RemoteFilePath + StrLen (RemoteFilePath); while ((--Walker) >= RemoteFilePath) { if ((*Walker == L'\\') || (*Walker == L'/' ) ) { break; } } LocalFilePath = Walker + 1; } // // Get the name of the Network Interface Card to be used if any. // UserNicName = ShellCommandLineGetValue (CheckPackage, L"-i"); ValueStr = ShellCommandLineGetValue (CheckPackage, L"-l"); if (ValueStr != NULL) { if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.LocalPort)) { goto Error; } } ValueStr = ShellCommandLineGetValue (CheckPackage, L"-r"); if (ValueStr != NULL) { if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.InitialServerPort)) { goto Error; } } ValueStr = ShellCommandLineGetValue (CheckPackage, L"-c"); if (ValueStr != NULL) { if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TryCount)) { goto Error; } } ValueStr = ShellCommandLineGetValue (CheckPackage, L"-t"); if (ValueStr != NULL) { if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TimeoutValue)) { goto Error; } if (Mtftp4ConfigData.TimeoutValue == 0) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellTftpHiiHandle, L"tftp", ValueStr ); goto Error; } } ValueStr = ShellCommandLineGetValue (CheckPackage, L"-s"); if (ValueStr != NULL) { if (!StringToUint16 (ValueStr, &BlockSize)) { goto Error; } if (BlockSize < MTFTP_MIN_BLKSIZE || BlockSize > MTFTP_MAX_BLKSIZE) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellTftpHiiHandle, L"tftp", ValueStr ); goto Error; } } // // Locate all MTFTP4 Service Binding protocols // ShellStatus = SHELL_NOT_FOUND; Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiManagedNetworkServiceBindingProtocolGuid, NULL, &HandleCount, &Handles ); if (EFI_ERROR (Status) || (HandleCount == 0)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NO_NIC), gShellTftpHiiHandle ); goto Error; } for (NicNumber = 0; (NicNumber < HandleCount) && (ShellStatus != SHELL_SUCCESS); NicNumber++) { ControllerHandle = Handles[NicNumber]; Data = NULL; Status = GetNicName (ControllerHandle, NicNumber, NicName); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NIC_NAME), gShellTftpHiiHandle, NicNumber, Status ); continue; } if (UserNicName != NULL) { if (StrCmp (NicName, UserNicName) != 0) { continue; } NicFound = TRUE; } Status = CreateServiceChildAndOpenProtocol ( ControllerHandle, &gEfiMtftp4ServiceBindingProtocolGuid, &gEfiMtftp4ProtocolGuid, &Mtftp4ChildHandle, (VOID**)&Mtftp4 ); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_OPEN_PROTOCOL), gShellTftpHiiHandle, NicName, Status ); continue; } Status = Mtftp4->Configure (Mtftp4, &Mtftp4ConfigData); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_CONFIGURE), gShellTftpHiiHandle, NicName, Status ); goto NextHandle; } Status = GetFileSize (Mtftp4, AsciiRemoteFilePath, &FileSize); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_FILE_SIZE), gShellTftpHiiHandle, RemoteFilePath, NicName, Status ); goto NextHandle; } Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, &Data); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD), gShellTftpHiiHandle, RemoteFilePath, NicName, Status ); goto NextHandle; } if (!EFI_ERROR (ShellFileExists (LocalFilePath))) { ShellDeleteFileByName (LocalFilePath); } Status = ShellOpenFileByName ( LocalFilePath, &FileHandle, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0 ); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellTftpHiiHandle, L"tftp", LocalFilePath ); goto NextHandle; } Status = ShellWriteFile (FileHandle, &FileSize, Data); if (!EFI_ERROR (Status)) { ShellStatus = SHELL_SUCCESS; } else { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_WRITE), gShellTftpHiiHandle, LocalFilePath, Status ); } ShellCloseFile (&FileHandle); NextHandle: if (Data != NULL) { gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Data, EFI_SIZE_TO_PAGES (FileSize)); } CloseProtocolAndDestroyServiceChild ( ControllerHandle, &gEfiMtftp4ServiceBindingProtocolGuid, &gEfiMtftp4ProtocolGuid, Mtftp4ChildHandle ); } if ((UserNicName != NULL) && (!NicFound)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NIC_NOT_FOUND), gShellTftpHiiHandle, UserNicName ); } Error: ShellCommandLineFreeVarList (CheckPackage); if (AsciiRemoteFilePath != NULL) { FreePool (AsciiRemoteFilePath); } if (Handles != NULL) { FreePool (Handles); } return ShellStatus; }
/** Installs the Device Recovery Module PPI, Initialize BlockIo Ppi installation notification @param FileHandle The file handle of the image. @param PeiServices General purpose services available to every PEIM. @retval EFI_SUCCESS The function completed successfully. @retval EFI_OUT_OF_RESOURCES There is not enough system memory. **/ EFI_STATUS EFIAPI CdExpressPeimEntry ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; PEI_CD_EXPRESS_PRIVATE_DATA *PrivateData; if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) { return EFI_SUCCESS; } PrivateData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (*PrivateData))); if (PrivateData == NULL) { return EFI_OUT_OF_RESOURCES; } mRecoveryFileNameSize = PcdGetSize(PcdRecoveryFileName) / sizeof(CHAR16); mRecoveryFileName = AllocatePool(mRecoveryFileNameSize); if (mRecoveryFileName == NULL) { return EFI_OUT_OF_RESOURCES; } Status = UnicodeStrToAsciiStrS(PcdGetPtr(PcdRecoveryFileName), mRecoveryFileName, mRecoveryFileNameSize); if (EFI_ERROR(Status)) { return Status; } // // Initialize Private Data (to zero, as is required by subsequent operations) // ZeroMem (PrivateData, sizeof (*PrivateData)); PrivateData->Signature = PEI_CD_EXPRESS_PRIVATE_DATA_SIGNATURE; PrivateData->BlockBuffer = AllocatePages (EFI_SIZE_TO_PAGES (PEI_CD_BLOCK_SIZE)); if (PrivateData->BlockBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } PrivateData->CapsuleCount = 0; Status = UpdateBlocksAndVolumes (PrivateData, TRUE); Status = UpdateBlocksAndVolumes (PrivateData, FALSE); // // Installs Ppi // PrivateData->DeviceRecoveryPpi.GetNumberRecoveryCapsules = GetNumberRecoveryCapsules; PrivateData->DeviceRecoveryPpi.GetRecoveryCapsuleInfo = GetRecoveryCapsuleInfo; PrivateData->DeviceRecoveryPpi.LoadRecoveryCapsule = LoadRecoveryCapsule; PrivateData->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); PrivateData->PpiDescriptor.Guid = &gEfiPeiDeviceRecoveryModulePpiGuid; PrivateData->PpiDescriptor.Ppi = &PrivateData->DeviceRecoveryPpi; Status = PeiServicesInstallPpi (&PrivateData->PpiDescriptor); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } // // PrivateData is allocated now, set it to the module variable // mPrivateData = PrivateData; // // Installs Block Io Ppi notification function // PrivateData->NotifyDescriptor.Flags = ( EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK ); PrivateData->NotifyDescriptor.Guid = &gEfiPeiVirtualBlockIoPpiGuid; PrivateData->NotifyDescriptor.Notify = BlockIoNotifyEntry; PrivateData->NotifyDescriptor2.Flags = ( EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST ); PrivateData->NotifyDescriptor2.Guid = &gEfiPeiVirtualBlockIo2PpiGuid; PrivateData->NotifyDescriptor2.Notify = BlockIoNotifyEntry; return PeiServicesNotifyPpi (&PrivateData->NotifyDescriptor); }