char *getpass(const char *Prompt) { BOOLEAN Ascii; CHAR16 *ReturnString; Ascii = FALSE; Print(L"%a", Prompt); ReturnString = ShellFileHandleReturnLine (gEfiShellParametersProtocol->StdIn, &Ascii); if (ReturnString == NULL) { return (NULL); } ReturnStringAscii = AllocateZeroPool((StrLen(ReturnString)+1)*sizeof(CHAR8)); if (ReturnStringAscii == NULL) { return (NULL); } UnicodeStrToAsciiStr(ReturnString, ReturnStringAscii); FreePool(ReturnString); return (ReturnStringAscii); }
/** Search for a file given its name coded in Ascii. When searching through the files of the volume, if a file is currently not open, its name was written on the media and is kept in RAM in the "HwDescription.Footer.Filename[]" field of the file's description. If a file is currently open, its name might not have been written on the media yet, and as the "HwDescription" is a mirror in RAM of what is on the media the "HwDescription.Footer.Filename[]" might be outdated. In that case, the up to date name of the file is stored in the "Info" field of the file's description. @param[in] Instance Pointer to the description of the volume in which the file has to be search for. @param[in] AsciiFileName Name of the file. @param[out] File Pointer to the description of the file if the file was found. @retval EFI_SUCCESS The file was found. @retval EFI_NOT_FOUND The file was not found. **/ EFI_STATUS BootMonGetFileFromAsciiFileName ( IN BOOTMON_FS_INSTANCE *Instance, IN CHAR8* AsciiFileName, OUT BOOTMON_FS_FILE **File ) { LIST_ENTRY *Entry; BOOTMON_FS_FILE *FileEntry; CHAR8 OpenFileAsciiFileName[MAX_NAME_LENGTH]; CHAR8 *AsciiFileNameToCompare; // Go through all the files in the list and return the file handle for (Entry = GetFirstNode (&Instance->RootFile->Link); !IsNull (&Instance->RootFile->Link, Entry); Entry = GetNextNode (&Instance->RootFile->Link, Entry) ) { FileEntry = BOOTMON_FS_FILE_FROM_LINK_THIS (Entry); if (FileEntry->Info != NULL) { UnicodeStrToAsciiStr (FileEntry->Info->FileName, OpenFileAsciiFileName); AsciiFileNameToCompare = OpenFileAsciiFileName; } else { AsciiFileNameToCompare = FileEntry->HwDescription.Footer.Filename; } if (AsciiStrCmp (AsciiFileNameToCompare, AsciiFileName) == 0) { *File = FileEntry; return EFI_SUCCESS; } } return EFI_NOT_FOUND; }
/** Update the string associated with an existing SMBIOS record. This function allows the update of specific SMBIOS strings. The number of valid strings for any SMBIOS record is defined by how many strings were present when Add() was called. @param[in] SmbiosHandle SMBIOS Handle of structure that will have its string updated. @param[in] StringNumber The non-zero string number of the string to update. @param[in] String Update the StringNumber string with String. @retval EFI_SUCCESS SmbiosHandle had its StringNumber String updated. @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist. Or String is invalid. @retval EFI_UNSUPPORTED String was not added because it is longer than the SMBIOS Table supports. @retval EFI_NOT_FOUND The StringNumber.is not valid for this SMBIOS record. **/ EFI_STATUS EFIAPI SmbiosLibUpdateUnicodeString ( IN EFI_SMBIOS_HANDLE SmbiosHandle, IN SMBIOS_TABLE_STRING StringNumber, IN CHAR16 *String ) { EFI_STATUS Status; UINTN StringIndex; CHAR8 *Ascii; if (String == NULL) { return EFI_INVALID_PARAMETER; } if (*String == '\0') { // A string with no data is not legal in SMBIOS return EFI_INVALID_PARAMETER; } Ascii = AllocateZeroPool (StrSize (String)); if (Ascii == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr (String, Ascii); StringIndex = StringNumber; Status = gSmbios->UpdateString (gSmbios, &SmbiosHandle, &StringIndex, Ascii); FreePool (Ascii); return Status; }
/** Fill in SPD_ENTRY_INDEXER through ParamPackage list. @param[in, out] Indexer The pointer to the SPD_ENTRY_INDEXER structure. @param[in] ParamPackage The pointer to the ParamPackage list. @retval EFI_SUCCESS Filled in SPD_ENTRY_INDEXER successfully. **/ EFI_STATUS ConstructSpdIndexer ( IN OUT SPD_ENTRY_INDEXER *Indexer, IN LIST_ENTRY *ParamPackage ) { EFI_STATUS Status; UINT64 Value64; CONST CHAR16 *ValueStr; ValueStr = NULL; if (ShellCommandLineGetFlag (ParamPackage, L"-i")) { ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i"); } else if (ShellCommandLineGetFlag (ParamPackage, L"-d")) { ValueStr = ShellCommandLineGetValue (ParamPackage, L"-d"); } else if (ShellCommandLineGetFlag (ParamPackage, L"-e")) { ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e"); } else { ASSERT (FALSE); } ASSERT (ValueStr != NULL); Value64 = StrToUInteger (ValueStr, &Status); if (!EFI_ERROR (Status)) { Indexer->Index = (UINTN) Value64; Indexer->Name = NULL; } else { UnicodeStrToAsciiStr (ValueStr, (CHAR8 *) Indexer->Name); } return EFI_SUCCESS; }
STATIC EFI_STATUS SetFileName ( IN BOOTMON_FS_FILE *File, IN CHAR16 *FileNameUnicode ) { CHAR8 *FileNameAscii; UINT16 SavedChar; UINTN FileNameSize; BOOTMON_FS_FILE *SameFile; EFI_STATUS Status; // EFI Shell inserts '\' in front of the filename that must be stripped if (FileNameUnicode[0] == L'\\') { FileNameUnicode++; } // // Convert Unicode into Ascii // SavedChar = L'\0'; FileNameSize = StrLen (FileNameUnicode) + 1; FileNameAscii = AllocatePool (FileNameSize * sizeof (CHAR8)); if (FileNameAscii == NULL) { return EFI_OUT_OF_RESOURCES; } // If Unicode string is too long then truncate it. if (FileNameSize > MAX_NAME_LENGTH) { SavedChar = FileNameUnicode[MAX_NAME_LENGTH - 1]; FileNameUnicode[MAX_NAME_LENGTH - 1] = L'\0'; } UnicodeStrToAsciiStr (FileNameUnicode, FileNameAscii); // If the unicode string was truncated then restore its original content. if (SavedChar != L'\0') { FileNameUnicode[MAX_NAME_LENGTH - 1] = SavedChar; } // If we're changing the file name if (AsciiStrCmp (FileNameAscii, File->HwDescription.Footer.Filename) == 0) { // No change to filename. Status = EFI_SUCCESS; } else if (!(File->OpenMode & EFI_FILE_MODE_WRITE)) { // You can only change the filename if you open the file for write. Status = EFI_ACCESS_DENIED; } else if (BootMonGetFileFromAsciiFileName ( File->Instance, File->HwDescription.Footer.Filename, &SameFile) != EFI_NOT_FOUND) { // A file with that name already exists. Status = EFI_ACCESS_DENIED; } else { // OK, change the filename. AsciiStrCpy (FileNameAscii, File->HwDescription.Footer.Filename); Status = EFI_SUCCESS; } FreePool (FileNameAscii); return Status; }
/** Transmit the HTTP mssage by processing the associated HTTP token. @param[in] Map The container of TxToken. @param[in] Item Current item to check against. @param[in] Context The Token to check againist. @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. @retval EFI_SUCCESS The HTTP message is queued into TCP transmit queue. **/ EFI_STATUS EFIAPI HttpTcpTransmit ( IN NET_MAP *Map, IN NET_MAP_ITEM *Item, IN VOID *Context ) { HTTP_TOKEN_WRAP *ValueInItem; EFI_STATUS Status; CHAR8 *RequestStr; CHAR8 *Url; ValueInItem = (HTTP_TOKEN_WRAP *) Item->Value; if (ValueInItem->TcpWrap.IsTxDone) { return EFI_SUCCESS; } // // Parse the URI of the remote host. // Url = AllocatePool (StrLen (ValueInItem->HttpToken->Message->Data.Request->Url) + 1); if (Url == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr (ValueInItem->HttpToken->Message->Data.Request->Url, Url); // // Create request message. // RequestStr = HttpGenRequestString ( ValueInItem->HttpInstance, ValueInItem->HttpToken->Message, Url ); FreePool (Url); if (RequestStr == NULL) { return EFI_OUT_OF_RESOURCES; } // // Transmit the request message. // Status = HttpTransmitTcp4 ( ValueInItem->HttpInstance, ValueInItem, (UINT8*) RequestStr, AsciiStrLen (RequestStr) ); FreePool (RequestStr); return Status; }
/** The getenv function searches an environment list, provided by the host environment, for a string that matches the string pointed to by name. The set of environment names and the method for altering the environment list are determined by the underlying UEFI Shell implementation. @return The getenv function returns a pointer to a string associated with the matched list member. The string pointed to shall not be modified by the program, but may be overwritten by a subsequent call to the getenv function. If the specified name cannot be found, a null pointer is returned. **/ char *getenv(const char *name) { const CHAR16 *EfiEnv; char *retval = NULL; (void)AsciiStrToUnicodeStr( name, gMD->UString); EfiEnv = ShellGetEnvironmentVariable(gMD->UString); if(EfiEnv != NULL) { retval = UnicodeStrToAsciiStr( EfiEnv, gMD->ASgetenv); } return retval; }
CHAR8* Unicode2Ascii ( CONST CHAR16* UnicodeStr ) { CHAR8* AsciiStr = AllocatePool((StrLen (UnicodeStr) + 1) * sizeof (CHAR8)); if (AsciiStr == NULL) { return NULL; } UnicodeStrToAsciiStr(UnicodeStr, AsciiStr); return AsciiStr; }
CHAR8 *get_pci_dev_path(pci_dt_t *PciDt) { // DBG("get_pci_dev_path"); CHAR8* tmp; CHAR16* devpathstr = NULL; EFI_DEVICE_PATH_PROTOCOL* DevicePath = NULL; DevicePath = DevicePathFromHandle (PciDt->DeviceHandle); if (!DevicePath) return NULL; devpathstr = FileDevicePathToStr(DevicePath); tmp = AllocateZeroPool((StrLen(devpathstr)+1)*sizeof(CHAR16)); UnicodeStrToAsciiStr(devpathstr, tmp); return tmp; }
INTN EFIAPI ShellAppMain ( IN UINTN Argc, IN CHAR16 **Argv ) { char FilenameA[32]; if(Argc == 2){ UnicodeStrToAsciiStr(FilenameA, Argv[1]); filename = FilenameA; } else filename = "test.wav"; UefiMain(gImageHandle, gST); }
EFI_STATUS EditHIInputAscii ( IN OUT CHAR8 *CmdLine, IN UINTN MaxCmdLine ) { CHAR16* Str; EFI_STATUS Status; Str = (CHAR16*)AllocatePool (MaxCmdLine * sizeof(CHAR16)); AsciiStrToUnicodeStr (CmdLine, Str); Status = EditHIInputStr (Str, MaxCmdLine); if (!EFI_ERROR(Status)) { UnicodeStrToAsciiStr (Str, CmdLine); } FreePool (Str); return Status; }
// Function to tell the firmware that OS X is being launched. This is // required to work around problems on some Macs that don't fully // initialize some hardware (especially video displays) when third-party // OSes are launched in EFI mode. EFI_STATUS SetAppleOSInfo() { CHAR16 *AppleOSVersion = NULL; CHAR8 *AppleOSVersion8 = NULL; EFI_STATUS Status; EFI_GUID apple_set_os_guid = EFI_APPLE_SET_OS_PROTOCOL_GUID; EfiAppleSetOsInterface *SetOs = NULL; Status = refit_call3_wrapper(BS->LocateProtocol, &apple_set_os_guid, NULL, (VOID**) &SetOs); // If not a Mac, ignore the call.... if ((Status != EFI_SUCCESS) || (!SetOs)) return EFI_SUCCESS; if ((SetOs->Version != 0) && GlobalConfig.SpoofOSXVersion) { AppleOSVersion = StrDuplicate(L"Mac OS X"); MergeStrings(&AppleOSVersion, GlobalConfig.SpoofOSXVersion, ' '); if (AppleOSVersion) { AppleOSVersion8 = AllocateZeroPool((StrLen(AppleOSVersion) + 1) * sizeof(CHAR8)); UnicodeStrToAsciiStr(AppleOSVersion, AppleOSVersion8); if (AppleOSVersion8) { Status = refit_call1_wrapper (SetOs->SetOsVersion, AppleOSVersion8); if (!EFI_ERROR(Status)) Status = EFI_SUCCESS; MyFreePool(AppleOSVersion8); } else { Status = EFI_OUT_OF_RESOURCES; Print(L"Out of resources in SetAppleOSInfo!\n"); } if ((Status == EFI_SUCCESS) && (SetOs->Version == 2)) Status = refit_call1_wrapper (SetOs->SetOsVendor, (CHAR8 *) "Apple Inc."); MyFreePool(AppleOSVersion); } // if (AppleOSVersion) } // if if (Status != EFI_SUCCESS) Print(L"Unable to set firmware boot type!\n"); return (Status); } // EFI_STATUS SetAppleOSInfo()
/** Allows a program to determine which secondary languages are supported on a given handle for a given primary language This routine is intended to be used by drivers to query the interface database for supported languages. This routine returns a string of concatenated 3-byte language identifiers, one per string package associated with the handle. @param This A pointer to the EFI_HII_PROTOCOL instance. @param Handle The handle on which the strings reside. Type EFI_HII_HANDLE is defined in EFI_HII_PROTOCOL.NewPack() in the Packages section. @param PrimaryLanguage Pointer to a NULL-terminated string containing a single ISO 639-2 language identifier, indicating the primary language. @param LanguageString A string allocated by GetSecondaryLanguages() containing a list of all secondary languages registered on the handle. The routine will not return the three-spaces language identifier used in other functions to indicate non-language-specific strings, nor will it return the primary language. This function succeeds but returns a NULL LanguageString if there are no secondary languages associated with the input Handle and PrimaryLanguage pair. Type EFI_STRING is defined in String. @retval EFI_SUCCESS LanguageString was correctly returned. @retval EFI_INVALID_PARAMETER The Handle was unknown. **/ EFI_STATUS EFIAPI HiiGetSecondaryLanguages ( IN EFI_HII_PROTOCOL *This, IN FRAMEWORK_EFI_HII_HANDLE Handle, IN CHAR16 *PrimaryLanguage, OUT EFI_STRING *LanguageString ) { HII_THUNK_PRIVATE_DATA *Private; EFI_HII_HANDLE UefiHiiHandle; CHAR8 *PrimaryLang4646; CHAR8 *PrimaryLang639; CHAR8 *SecLangCodes4646; CHAR8 *SecLangCodes639; CHAR16 *UnicodeSecLangCodes639; EFI_STATUS Status; Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This); SecLangCodes639 = NULL; SecLangCodes4646 = NULL; PrimaryLang4646 = NULL; UnicodeSecLangCodes639 = NULL; UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle); if (UefiHiiHandle == NULL) { return EFI_INVALID_PARAMETER; } PrimaryLang639 = AllocateZeroPool (StrLen (PrimaryLanguage) + 1); if (PrimaryLang639 == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Done; } UnicodeStrToAsciiStr (PrimaryLanguage, PrimaryLang639); PrimaryLang4646 = ConvertLanguagesIso639ToRfc4646 (PrimaryLang639); ASSERT_EFI_ERROR (PrimaryLang4646 != NULL); SecLangCodes4646 = HiiGetSupportedSecondaryLanguages (UefiHiiHandle, PrimaryLang4646); if (SecLangCodes4646 == NULL) { Status = EFI_INVALID_PARAMETER; goto Done; } SecLangCodes639 = ConvertLanguagesIso639ToRfc4646 (SecLangCodes4646); if (SecLangCodes639 == NULL) { Status = EFI_INVALID_PARAMETER; goto Done; } UnicodeSecLangCodes639 = AllocateZeroPool (AsciiStrSize (SecLangCodes639) * sizeof (CHAR16)); if (UnicodeSecLangCodes639 == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Done; } // // The language returned is in RFC 4646 format. // *LanguageString = AsciiStrToUnicodeStr (SecLangCodes639, UnicodeSecLangCodes639); Status = EFI_SUCCESS; Done: if (PrimaryLang639 != NULL) { FreePool (PrimaryLang639); } if (SecLangCodes639 != NULL) { FreePool (SecLangCodes639); } if (PrimaryLang4646 != NULL) { FreePool (PrimaryLang4646); } if (SecLangCodes4646 != NULL) { FreePool (SecLangCodes4646); } if (UnicodeSecLangCodes639 != NULL) { FreePool (UnicodeSecLangCodes639); } return Status; }
/** Opens a file on the Nor Flash FS volume Calls BootMonFsGetFileFromAsciiFilename to search the list of tracked files. @param This The EFI_FILE_PROTOCOL parent handle. @param NewHandle Double-pointer to the newly created protocol. @param FileName The name of the image/metadata on flash @param OpenMode Read,write,append etc @param Attributes ? @return EFI_STATUS OUT_OF_RESOURCES Run out of space to keep track of the allocated structures DEVICE_ERROR Unable to locate the volume associated with the parent file handle NOT_FOUND Filename wasn't found on flash SUCCESS **/ EFIAPI EFI_STATUS BootMonFsOpenFile ( IN EFI_FILE_PROTOCOL *This, OUT EFI_FILE_PROTOCOL **NewHandle, IN CHAR16 *FileName, IN UINT64 OpenMode, IN UINT64 Attributes ) { BOOTMON_FS_FILE *Directory; BOOTMON_FS_FILE *File; BOOTMON_FS_INSTANCE *Instance; CHAR8* AsciiFileName; EFI_STATUS Status; if ((FileName == NULL) || (NewHandle == NULL)) { return EFI_INVALID_PARAMETER; } // The only valid modes are read, read/write, and read/write/create if (!(OpenMode & EFI_FILE_MODE_READ) || ((OpenMode & EFI_FILE_MODE_CREATE) && !(OpenMode & EFI_FILE_MODE_WRITE))) { return EFI_INVALID_PARAMETER; } Directory = BOOTMON_FS_FILE_FROM_FILE_THIS (This); if (Directory == NULL) { return EFI_DEVICE_ERROR; } Instance = Directory->Instance; // If the instance has not been initialized it yet then do it ... if (!Instance->Initialized) { Status = BootMonFsInitialize (Instance); if (EFI_ERROR (Status)) { return Status; } } // BootMonFs interface requires ASCII filenames AsciiFileName = AllocatePool ((StrLen (FileName) + 1) * sizeof (CHAR8)); if (AsciiFileName == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr (FileName, AsciiFileName); if ((AsciiStrCmp (AsciiFileName, "\\") == 0) || (AsciiStrCmp (AsciiFileName, "/") == 0) || (AsciiStrCmp (AsciiFileName, "") == 0) || (AsciiStrCmp (AsciiFileName, ".") == 0)) { // // Opening '/', '\', '.', or the NULL pathname is trying to open the root directory // *NewHandle = &Instance->RootFile->File; Instance->RootFile->Position = 0; Status = EFI_SUCCESS; } else { // // Open or Create a regular file // // Check if the file already exists Status = BootMonGetFileFromAsciiFileName (Instance, AsciiFileName, &File); if (Status == EFI_NOT_FOUND) { // The file doesn't exist. if (OpenMode & EFI_FILE_MODE_CREATE) { // If the file does not exist but is required then create it. if (Attributes & EFI_FILE_DIRECTORY) { // BootMonFS doesn't support subdirectories Status = EFI_UNSUPPORTED; } else { // Create a new file Status = CreateNewFile (Instance, AsciiFileName, &File); if (!EFI_ERROR (Status)) { File->OpenMode = OpenMode; *NewHandle = &File->File; File->Position = 0; } } } } else if (Status == EFI_SUCCESS) { // The file exists File->OpenMode = OpenMode; *NewHandle = &File->File; File->Position = 0; } } FreePool (AsciiFileName); return Status; }
/** Download an image from a TFTP server @param[in] DevicePath Device path of the TFTP boot option @param[in] ControllerHandle Handle of the network controller @param[in] RemainingDevicePath Device path of the TFTP boot option but the first node that identifies the network controller @param[in] Type Type to allocate memory pages @param[out] Image Address of the bufer where the image is stored in case of success @param[out] ImageSize Size in number of bytes of the i;age in case of success @retval EFI_SUCCESS The image was returned. @retval !EFI_SUCCESS Something went wrong. **/ EFI_STATUS BdsTftpLoadImage ( IN OUT EFI_DEVICE_PATH **DevicePath, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH *RemainingDevicePath, IN EFI_ALLOCATE_TYPE Type, IN OUT EFI_PHYSICAL_ADDRESS *Image, OUT UINTN *ImageSize ) { EFI_STATUS Status; EFI_HANDLE Dhcp4ChildHandle; EFI_DHCP4_PROTOCOL *Dhcp4; BOOLEAN Dhcp4ToStop; EFI_HANDLE Mtftp4ChildHandle; EFI_MTFTP4_PROTOCOL *Mtftp4; DHCP4_OPTION ParaList; EFI_DHCP4_PACKET_OPTION *OptionList[2]; EFI_DHCP4_CONFIG_DATA Dhcp4CfgData; EFI_DHCP4_MODE_DATA Dhcp4Mode; EFI_MTFTP4_CONFIG_DATA Mtftp4CfgData; IPv4_DEVICE_PATH *IPv4DevicePathNode; FILEPATH_DEVICE_PATH *FilePathDevicePathNode; CHAR8 *AsciiFilePath; EFI_MTFTP4_TOKEN Mtftp4Token; UINT64 FileSize; UINT64 TftpBufferSize; BDS_TFTP_CONTEXT *TftpContext; ASSERT(IS_DEVICE_PATH_NODE (RemainingDevicePath, MESSAGING_DEVICE_PATH, MSG_IPv4_DP)); IPv4DevicePathNode = (IPv4_DEVICE_PATH*)RemainingDevicePath; Dhcp4ChildHandle = NULL; Dhcp4 = NULL; Dhcp4ToStop = FALSE; Mtftp4ChildHandle = NULL; Mtftp4 = NULL; AsciiFilePath = NULL; TftpContext = NULL; if (!IPv4DevicePathNode->StaticIpAddress) { // // Using the DHCP4 Service Binding Protocol, create a child handle of the DHCP4 service and // install the DHCP4 protocol on it. Then, open the DHCP protocol. // Status = NetLibCreateServiceChild ( ControllerHandle, gImageHandle, &gEfiDhcp4ServiceBindingProtocolGuid, &Dhcp4ChildHandle ); if (!EFI_ERROR (Status)) { Status = gBS->OpenProtocol ( Dhcp4ChildHandle, &gEfiDhcp4ProtocolGuid, (VOID **) &Dhcp4, gImageHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER ); } if (EFI_ERROR (Status)) { Print (L"Unable to open DHCP4 protocol\n"); goto Error; } } // // Using the MTFTP4 Service Binding Protocol, create a child handle of the MTFTP4 service and // install the MTFTP4 protocol on it. Then, open the MTFTP4 protocol. // Status = NetLibCreateServiceChild ( ControllerHandle, gImageHandle, &gEfiMtftp4ServiceBindingProtocolGuid, &Mtftp4ChildHandle ); if (!EFI_ERROR (Status)) { Status = gBS->OpenProtocol ( Mtftp4ChildHandle, &gEfiMtftp4ProtocolGuid, (VOID **) &Mtftp4, gImageHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER ); } if (EFI_ERROR (Status)) { Print (L"Unable to open MTFTP4 protocol\n"); goto Error; } if (!IPv4DevicePathNode->StaticIpAddress) { // // Configure the DHCP4, all default settings. It is acceptable for the configuration to // fail if the return code is equal to EFI_ACCESS_DENIED which means that the configuration // has been done by another instance of the DHCP4 protocol or that the DHCP configuration // process has been started but is not completed yet. // ZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA)); ParaList.Head.OpCode = DHCP_TAG_PARA_LIST; ParaList.Head.Length = 2; ParaList.Head.Data[0] = DHCP_TAG_NETMASK; ParaList.Route = DHCP_TAG_ROUTER; OptionList[0] = &ParaList.Head; Dhcp4CfgData.OptionCount = 1; Dhcp4CfgData.OptionList = OptionList; Status = Dhcp4->Configure (Dhcp4, &Dhcp4CfgData); if (EFI_ERROR (Status)) { if (Status != EFI_ACCESS_DENIED) { Print (L"Error while configuring the DHCP4 protocol\n"); goto Error; } } // // Start the DHCP configuration. This may have already been done thus do not leave in error // if the return code is EFI_ALREADY_STARTED. // Status = Dhcp4->Start (Dhcp4, NULL); if (EFI_ERROR (Status)) { if (Status != EFI_ALREADY_STARTED) { Print (L"DHCP configuration failed\n"); goto Error; } } else { Dhcp4ToStop = TRUE; } Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode); if (EFI_ERROR (Status)) { goto Error; } if (Dhcp4Mode.State != Dhcp4Bound) { Status = EFI_TIMEOUT; Print (L"DHCP configuration failed\n"); goto Error; } } // // Configure the TFTP4 protocol // ZeroMem (&Mtftp4CfgData, sizeof (EFI_MTFTP4_CONFIG_DATA)); Mtftp4CfgData.UseDefaultSetting = FALSE; Mtftp4CfgData.TimeoutValue = 4; Mtftp4CfgData.TryCount = 6; if (IPv4DevicePathNode->StaticIpAddress) { CopyMem (&Mtftp4CfgData.StationIp , &IPv4DevicePathNode->LocalIpAddress, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&Mtftp4CfgData.SubnetMask, &IPv4DevicePathNode->SubnetMask, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&Mtftp4CfgData.GatewayIp , &IPv4DevicePathNode->GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS)); } else { CopyMem (&Mtftp4CfgData.StationIp , &Dhcp4Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&Mtftp4CfgData.SubnetMask, &Dhcp4Mode.SubnetMask , sizeof (EFI_IPv4_ADDRESS)); CopyMem (&Mtftp4CfgData.GatewayIp , &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS)); } CopyMem (&Mtftp4CfgData.ServerIp , &IPv4DevicePathNode->RemoteIpAddress, sizeof (EFI_IPv4_ADDRESS)); Status = Mtftp4->Configure (Mtftp4, &Mtftp4CfgData); if (EFI_ERROR (Status)) { Print (L"Error while configuring the MTFTP4 protocol\n"); goto Error; } // // Convert the Unicode path of the file to Ascii // FilePathDevicePathNode = (FILEPATH_DEVICE_PATH*)(IPv4DevicePathNode + 1); AsciiFilePath = AllocatePool ((StrLen (FilePathDevicePathNode->PathName) + 1) * sizeof (CHAR8)); if (AsciiFilePath == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error; } UnicodeStrToAsciiStr (FilePathDevicePathNode->PathName, AsciiFilePath); // // Try to get the size of the file in bytes from the server. If it fails, // start with a 8MB buffer to download the file. // FileSize = 0; if (Mtftp4GetFileSize (Mtftp4, AsciiFilePath, &FileSize) == EFI_SUCCESS) { TftpBufferSize = FileSize; } else { TftpBufferSize = SIZE_8MB; } TftpContext = AllocatePool (sizeof (BDS_TFTP_CONTEXT)); if (TftpContext == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error; } TftpContext->FileSize = FileSize; for (; TftpBufferSize <= FixedPcdGet32 (PcdMaxTftpFileSize); TftpBufferSize = (TftpBufferSize + SIZE_8MB) & (~(SIZE_8MB-1))) { // // Allocate a buffer to hold the whole file. // Status = gBS->AllocatePages ( Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES (TftpBufferSize), Image ); if (EFI_ERROR (Status)) { Print (L"Failed to allocate space for image\n"); goto Error; } TftpContext->DownloadedNbOfBytes = 0; TftpContext->LastReportedNbOfBytes = 0; ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN)); Mtftp4Token.Filename = (UINT8*)AsciiFilePath; Mtftp4Token.BufferSize = TftpBufferSize; Mtftp4Token.Buffer = (VOID *)(UINTN)*Image; Mtftp4Token.CheckPacket = Mtftp4CheckPacket; Mtftp4Token.Context = (VOID*)TftpContext; Print (L"Downloading the file <%s> from the TFTP server\n", FilePathDevicePathNode->PathName); Status = Mtftp4->ReadFile (Mtftp4, &Mtftp4Token); Print (L"\n"); if (EFI_ERROR (Status)) { gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize)); if (Status == EFI_BUFFER_TOO_SMALL) { Print (L"Downloading failed, file larger than expected.\n"); continue; } else { goto Error; } } *ImageSize = Mtftp4Token.BufferSize; break; } Error: if (Dhcp4ChildHandle != NULL) { if (Dhcp4 != NULL) { if (Dhcp4ToStop) { Dhcp4->Stop (Dhcp4); } gBS->CloseProtocol ( Dhcp4ChildHandle, &gEfiDhcp4ProtocolGuid, gImageHandle, ControllerHandle ); } NetLibDestroyServiceChild ( ControllerHandle, gImageHandle, &gEfiDhcp4ServiceBindingProtocolGuid, Dhcp4ChildHandle ); } if (Mtftp4ChildHandle != NULL) { if (Mtftp4 != NULL) { if (AsciiFilePath != NULL) { FreePool (AsciiFilePath); } if (TftpContext != NULL) { FreePool (TftpContext); } gBS->CloseProtocol ( Mtftp4ChildHandle, &gEfiMtftp4ProtocolGuid, gImageHandle, ControllerHandle ); } NetLibDestroyServiceChild ( ControllerHandle, gImageHandle, &gEfiMtftp4ServiceBindingProtocolGuid, Mtftp4ChildHandle ); } if (EFI_ERROR (Status)) { Print (L"Failed to download the file - Error=%r\n", Status); } return Status; }
/** 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; 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; ShellStatus = SHELL_INVALID_PARAMETER; ProblemParam = NULL; NicFound = FALSE; AsciiRemoteFilePath = NULL; Handles = NULL; FileSize = 0; // // 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); AsciiRemoteFilePath = AllocatePool ( (StrLen (RemoteFilePath) + 1) * sizeof (CHAR8) ); if (AsciiRemoteFilePath == NULL) { ShellStatus = SHELL_OUT_OF_RESOURCES; goto Error; } UnicodeStrToAsciiStr (RemoteFilePath, AsciiRemoteFilePath); 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; } } // // 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, &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; }
/** Add new boot option for HTTP boot. @param[in] Private Pointer to the driver private data. @param[in] UsingIpv6 Set to TRUE if creating boot option for IPv6. @param[in] Description The description text of the boot option. @param[in] Uri The URI string of the boot file. @retval EFI_SUCCESS The boot option is created successfully. @retval Others Failed to create new boot option. **/ EFI_STATUS HttpBootAddBootOption ( IN HTTP_BOOT_PRIVATE_DATA *Private, IN BOOLEAN UsingIpv6, IN CHAR16 *Description, IN CHAR16 *Uri ) { EFI_DEV_PATH *Node; EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath; EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; UINTN Length; CHAR8 AsciiUri[URI_STR_MAX_SIZE]; CHAR16 *CurrentOrder; EFI_STATUS Status; UINTN OrderCount; UINTN TargetLocation; BOOLEAN Found; UINT8 *TempByteBuffer; UINT8 *TempByteStart; UINTN DescSize; UINTN FilePathSize; CHAR16 OptionStr[10]; UINT16 *NewOrder; UINTN Index; NewOrder = NULL; TempByteStart = NULL; NewDevicePath = NULL; NewOrder = NULL; Node = NULL; TmpDevicePath = NULL; CurrentOrder = NULL; if (StrLen (Description) == 0) { return EFI_INVALID_PARAMETER; } // // Convert the scheme to all lower case. // for (Index = 0; Index < StrLen (Uri); Index++) { if (Uri[Index] == L':') { break; } if (Uri[Index] >= L'A' && Uri[Index] <= L'Z') { Uri[Index] -= (CHAR16)(L'A' - L'a'); } } // // Only accept http and https URI. // if ((StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 7) != 0)) { return EFI_INVALID_PARAMETER; } // // Create a new device path by appending the IP node and URI node to // the driver's parent device path // if (!UsingIpv6) { Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH)); if (Node == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH; Node->Ipv4.Header.SubType = MSG_IPv4_DP; SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH)); } else { Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH)); if (Node == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } Node->Ipv6.Header.Type = MESSAGING_DEVICE_PATH; Node->Ipv6.Header.SubType = MSG_IPv6_DP; SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH)); } TmpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node); FreePool (Node); if (TmpDevicePath == NULL) { return EFI_OUT_OF_RESOURCES; } // // Update the URI node with the input boot file URI. // UnicodeStrToAsciiStr (Uri, AsciiUri); Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (AsciiUri); Node = AllocatePool (Length); if (Node == NULL) { Status = EFI_OUT_OF_RESOURCES; FreePool (TmpDevicePath); goto ON_EXIT; } Node->DevPath.Type = MESSAGING_DEVICE_PATH; Node->DevPath.SubType = MSG_URI_DP; SetDevicePathNodeLength (Node, Length); CopyMem ((UINT8*) Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), AsciiUri, AsciiStrSize (AsciiUri)); NewDevicePath = AppendDevicePathNode (TmpDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node); FreePool (Node); FreePool (TmpDevicePath); if (NewDevicePath == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } // // Get current "BootOrder" variable and find a free target. // Length = 0; Status = GetVariable2 ( L"BootOrder", &gEfiGlobalVariableGuid, (VOID **)&CurrentOrder, &Length ); if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) { goto ON_EXIT; } OrderCount = Length / sizeof (UINT16); Found = FALSE; for (TargetLocation=0; TargetLocation < 0xFFFF; TargetLocation++) { Found = TRUE; for (Index = 0; Index < OrderCount; Index++) { if (CurrentOrder[Index] == TargetLocation) { Found = FALSE; break; } } if (Found) { break; } } if (TargetLocation == 0xFFFF) { DEBUG ((EFI_D_ERROR, "Could not find unused target index.\n")); Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } else { DEBUG ((EFI_D_INFO, "TargetIndex = %04x.\n", TargetLocation)); } // // Construct and set the "Boot####" variable // DescSize = StrSize(Description); FilePathSize = GetDevicePathSize (NewDevicePath); TempByteBuffer = AllocateZeroPool(sizeof(EFI_LOAD_OPTION) + DescSize + FilePathSize); if (TempByteBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } TempByteStart = TempByteBuffer; *((UINT32 *) TempByteBuffer) = LOAD_OPTION_ACTIVE; // Attributes TempByteBuffer += sizeof (UINT32); *((UINT16 *) TempByteBuffer) = (UINT16)FilePathSize; // FilePathListLength TempByteBuffer += sizeof (UINT16); CopyMem (TempByteBuffer, Description, DescSize); TempByteBuffer += DescSize; CopyMem (TempByteBuffer, NewDevicePath, FilePathSize); UnicodeSPrint (OptionStr, sizeof(OptionStr), L"%s%04x", L"Boot", TargetLocation); Status = gRT->SetVariable ( OptionStr, &gEfiGlobalVariableGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize, TempByteStart ); if (EFI_ERROR (Status)) { goto ON_EXIT; } // // Insert into the order list and set "BootOrder" variable // NewOrder = AllocateZeroPool ((OrderCount + 1) * sizeof (UINT16)); if (NewOrder == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } CopyMem(NewOrder, CurrentOrder, OrderCount * sizeof(UINT16)); NewOrder[OrderCount] = (UINT16) TargetLocation; Status = gRT->SetVariable ( L"BootOrder", &gEfiGlobalVariableGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, ((OrderCount + 1) * sizeof (UINT16)), NewOrder ); ON_EXIT: if (CurrentOrder != NULL) { FreePool (CurrentOrder); } if (NewOrder != NULL) { FreePool (NewOrder); } if (TempByteStart != NULL) { FreePool (TempByteStart); } if (NewDevicePath != NULL) { FreePool (NewDevicePath); } return Status; }
/** Set information about a file. @param[in] Fcb A pointer to the description of the open file. @param[in] Info A pointer to the file information to write. @retval EFI_SUCCESS The information was set. @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file to a file that is already present. @retval EFI_ACCESS_DENIED An attempt is being made to change the EFI_FILE_DIRECTORY Attribute. @retval EFI_ACCESS_DENIED The file is a read-only file or has been opened in read-only mode and an attempt is being made to modify a field other than Attribute. @retval EFI_WRITE_PROTECTED An attempt is being made to modify a read-only attribute. @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed. @retval EFI_OUT_OF_RESOURCES A allocation needed to process the request failed. **/ STATIC EFI_STATUS SetFileInfo ( IN SEMIHOST_FCB *Fcb, IN EFI_FILE_INFO *Info ) { EFI_STATUS Status; RETURN_STATUS Return; BOOLEAN FileSizeIsDifferent; BOOLEAN FileNameIsDifferent; BOOLEAN ReadOnlyIsDifferent; CHAR8 *AsciiFileName; UINTN FileSize; UINTN Length; UINTN SemihostHandle; // // A directory can not be changed to a file and a file can // not be changed to a directory. // if (((Info->Attribute & EFI_FILE_DIRECTORY) != 0) != Fcb->IsRoot) { return EFI_ACCESS_DENIED; } AsciiFileName = AllocatePool (StrLen (Info->FileName) + 1); if (AsciiFileName == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr (Info->FileName, AsciiFileName); FileSizeIsDifferent = (Info->FileSize != Fcb->Info.FileSize); FileNameIsDifferent = (AsciiStrCmp (AsciiFileName, Fcb->FileName) != 0); ReadOnlyIsDifferent = CompareMem ( &Info->CreateTime, &Fcb->Info.CreateTime, 3 * sizeof (EFI_TIME) ) != 0; // // For a read-only file or a file opened in read-only mode, only // the Attribute field can be modified. As the root directory is // read-only (i.e. VolumeOpen()), this protects the root directory // description. // if ((Fcb->OpenMode == EFI_FILE_MODE_READ) || (Fcb->Info.Attribute & EFI_FILE_READ_ONLY) ) { if (FileSizeIsDifferent || FileNameIsDifferent || ReadOnlyIsDifferent) { Status = EFI_ACCESS_DENIED; goto Error; } } if (ReadOnlyIsDifferent) { Status = EFI_WRITE_PROTECTED; goto Error; } Status = EFI_DEVICE_ERROR; if (FileSizeIsDifferent) { FileSize = Info->FileSize; if (Fcb->Info.FileSize < FileSize) { Status = ExtendFile (Fcb, FileSize - Fcb->Info.FileSize); if (EFI_ERROR (Status)) { goto Error; } // // The read/write position from the host file system point of view // is at the end of the file. If the position from this module // point of view is smaller than the new file size, then // ask the host file system to move to that position. // if (Fcb->Position < FileSize) { FileSetPosition (&Fcb->File, Fcb->Position); } } Fcb->Info.FileSize = FileSize; Return = SemihostFileLength (Fcb->SemihostHandle, &Length); if (RETURN_ERROR (Return)) { goto Error; } Fcb->Info.PhysicalSize = Length; } // // Note down in RAM the Attribute field but we can not ask // for its modification to the host file system as the // semi-host interface does not provide this feature. // Fcb->Info.Attribute = Info->Attribute; if (FileNameIsDifferent) { Return = SemihostFileOpen ( AsciiFileName, SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY, &SemihostHandle ); if (!RETURN_ERROR (Return)) { SemihostFileClose (SemihostHandle); Status = EFI_ACCESS_DENIED; goto Error; } Return = SemihostFileRename (Fcb->FileName, AsciiFileName); if (RETURN_ERROR (Return)) { goto Error; } FreePool (Fcb->FileName); Fcb->FileName = AsciiFileName; AsciiFileName = NULL; } Status = EFI_SUCCESS; Error: if (AsciiFileName != NULL) { FreePool (AsciiFileName); } return Status; }
EFI_STATUS DefineDefaultBootEntries ( VOID ) { BDS_LOAD_OPTION* BdsLoadOption; UINTN Size; EFI_STATUS Status; EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol; EFI_DEVICE_PATH* BootDevicePath; UINTN CmdLineSize; UINTN CmdLineAsciiSize; CHAR16* DefaultBootArgument; CHAR8* AsciiDefaultBootArgument; // // If Boot Order does not exist then create a default entry // Size = 0; Status = gRT->GetVariable (L"BootOrder", &gEfiGlobalVariableGuid, NULL, &Size, NULL); if (Status == EFI_NOT_FOUND) { if ((PcdGetPtr(PcdDefaultBootDevicePath) == NULL) || (StrLen ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)) == 0)) { return EFI_UNSUPPORTED; } Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); if (EFI_ERROR(Status)) { // You must provide an implementation of DevicePathFromTextProtocol in your firmware (eg: DevicePathDxe) DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathFromTextProtocol\n")); return Status; } BootDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)); DEBUG_CODE_BEGIN(); // We convert back to the text representation of the device Path to see if the initial text is correct EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; CHAR16* DevicePathTxt; Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); ASSERT_EFI_ERROR(Status); DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootDevicePath, TRUE, TRUE); if (StrCmp ((CHAR16*)PcdGetPtr (PcdDefaultBootDevicePath), DevicePathTxt) != 0) { DEBUG ((EFI_D_ERROR, "Device Path given: '%s' Device Path expected: '%s'\n", (CHAR16*)PcdGetPtr (PcdDefaultBootDevicePath), DevicePathTxt)); ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); } FreePool (DevicePathTxt); DEBUG_CODE_END(); // Create the entry is the Default values are correct if (BootDevicePath != NULL) { // We do not support NULL pointer ASSERT (PcdGetPtr (PcdDefaultBootArgument) != NULL); // // Logic to handle ASCII or Unicode default parameters // if (*(CHAR8*)PcdGetPtr (PcdDefaultBootArgument) == '\0') { CmdLineSize = 0; CmdLineAsciiSize = 0; DefaultBootArgument = NULL; AsciiDefaultBootArgument = NULL; } else if (IsUnicodeString ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument))) { // The command line is a Unicode string DefaultBootArgument = (CHAR16*)PcdGetPtr (PcdDefaultBootArgument); CmdLineSize = StrSize (DefaultBootArgument); // Initialize ASCII variables CmdLineAsciiSize = CmdLineSize / 2; AsciiDefaultBootArgument = AllocatePool (CmdLineAsciiSize); if (AsciiDefaultBootArgument == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument), AsciiDefaultBootArgument); } else { // The command line is a ASCII string AsciiDefaultBootArgument = (CHAR8*)PcdGetPtr (PcdDefaultBootArgument); CmdLineAsciiSize = AsciiStrSize (AsciiDefaultBootArgument); // Initialize ASCII variables CmdLineSize = CmdLineAsciiSize * 2; DefaultBootArgument = AllocatePool (CmdLineSize); if (DefaultBootArgument == NULL) { return EFI_OUT_OF_RESOURCES; } AsciiStrToUnicodeStr (AsciiDefaultBootArgument, DefaultBootArgument); } BootOptionCreate (LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT, (CHAR16*)PcdGetPtr (PcdDefaultBootDescription), BootDevicePath, (UINT8 *)DefaultBootArgument, // OptionalData CmdLineSize, // OptionalDataSize &BdsLoadOption ); FreePool (BdsLoadOption); if (DefaultBootArgument == (CHAR16*)PcdGetPtr (PcdDefaultBootArgument)) { FreePool (AsciiDefaultBootArgument); } else if (DefaultBootArgument != NULL) { FreePool (DefaultBootArgument); } } else { Status = EFI_UNSUPPORTED; } } return Status; }
/** Create or update a String Token in a String Package. If *Reference == 0, a new String Token is created. @param This A pointer to the EFI_HII_PROTOCOL instance. @param Language Pointer to a NULL-terminated string containing a single ISO 639-2 language identifier, indicating the language to print. A string consisting of all spaces indicates that the string is applicable to all languages. @param Handle The handle of the language pack to which the string is to be added. @param Reference The string token assigned to the string. @param NewString The string to be added. @retval EFI_SUCCESS The string was effectively registered. @retval EFI_INVALID_PARAMETER The Handle was unknown. The string is not created or updated in the the string package. **/ EFI_STATUS EFIAPI HiiNewString ( IN EFI_HII_PROTOCOL *This, IN CHAR16 *Language, IN FRAMEWORK_EFI_HII_HANDLE Handle, IN OUT STRING_REF *Reference, IN CHAR16 *NewString ) { EFI_STATUS Status; HII_THUNK_PRIVATE_DATA *Private; EFI_GUID TagGuid; LIST_ENTRY *Link; HII_THUNK_CONTEXT *ThunkContext; HII_THUNK_CONTEXT *StringPackThunkContext; EFI_STRING_ID StringId; EFI_STRING_ID LastStringId; CHAR8 AsciiLanguage[ISO_639_2_ENTRY_SIZE + 1]; CHAR16 LanguageCopy[ISO_639_2_ENTRY_SIZE + 1]; CHAR8 *Rfc4646AsciiLanguage; LastStringId = (EFI_STRING_ID) 0; StringId = (EFI_STRING_ID) 0; Rfc4646AsciiLanguage = NULL; if (Language != NULL) { ZeroMem (AsciiLanguage, sizeof (AsciiLanguage));; ZeroMem (LanguageCopy, sizeof (LanguageCopy)); CopyMem (LanguageCopy, Language, ISO_639_2_ENTRY_SIZE * sizeof (CHAR16)); UnicodeStrToAsciiStr (LanguageCopy, AsciiLanguage); Rfc4646AsciiLanguage = ConvertLanguagesIso639ToRfc4646 (AsciiLanguage); ASSERT (Rfc4646AsciiLanguage != NULL); } Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This); StringPackThunkContext = FwHiiHandleToThunkContext (Private, Handle); if (StringPackThunkContext == NULL) { return EFI_INVALID_PARAMETER; } if (StringPackThunkContext->SharingStringPack) { Status = GetTagGuidByFwHiiHandle (Private, Handle, &TagGuid); ASSERT_EFI_ERROR (Status); Link = GetFirstNode (&Private->ThunkContextListHead); while (!IsNull (&Private->ThunkContextListHead, Link)) { ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link); if (CompareGuid (&TagGuid, &ThunkContext->TagGuid)) { if (ThunkContext->SharingStringPack) { StringId = *Reference; Status = UpdateString (ThunkContext, Rfc4646AsciiLanguage, NewString, &StringId); if (EFI_ERROR (Status)) { break; } DEBUG_CODE_BEGIN (); if (*Reference == 0) { // // When creating new string token, make sure all created token is the same // for all string packages registered using FW HII interface. // if (LastStringId == (EFI_STRING_ID) 0) { LastStringId = StringId; } else { if (LastStringId != StringId) { ASSERT(FALSE); } } } DEBUG_CODE_END (); } } Link = GetNextNode (&Private->ThunkContextListHead, Link); } } else { StringId = *Reference; Status = UpdateString (StringPackThunkContext, Rfc4646AsciiLanguage, NewString, &StringId); } if (!EFI_ERROR (Status)) { if (*Reference == 0) { *Reference = StringId; } } else { // // Only EFI_INVALID_PARAMETER is defined in HII 0.92 specification. // Status = EFI_INVALID_PARAMETER; } return Status; }
/** This function extracts a string from a package already registered with the EFI HII database. @param This A pointer to the EFI_HII_PROTOCOL instance. @param Handle The HII handle on which the string resides. @param Token The string token assigned to the string. @param Raw If TRUE, the string is returned unedited in the internal storage format described above. If false, the string returned is edited by replacing <cr> with <space> and by removing special characters such as the <wide> prefix. @param LanguageString Pointer to a NULL-terminated string containing a single ISO 639-2 language identifier, indicating the language to print. If the LanguageString is empty (starts with a NULL), the default system language will be used to determine the language. @param BufferLength Length of the StringBuffer. If the status reports that the buffer width is too small, this parameter is filled with the length of the buffer needed. @param StringBuffer The buffer designed to receive the characters in the string. Type EFI_STRING is defined in String. @retval EFI_INVALID_PARAMETER If input parameter is invalid. @retval EFI_BUFFER_TOO_SMALL If the *BufferLength is too small. @retval EFI_SUCCESS Operation is successful. **/ EFI_STATUS EFIAPI HiiThunkGetString ( IN EFI_HII_PROTOCOL *This, IN FRAMEWORK_EFI_HII_HANDLE Handle, IN STRING_REF Token, IN BOOLEAN Raw, IN CHAR16 *LanguageString, IN OUT UINTN *BufferLength, OUT EFI_STRING StringBuffer ) { HII_THUNK_PRIVATE_DATA *Private; CHAR8 *Iso639AsciiLanguage; CHAR8 *Rfc4646AsciiLanguage; CHAR8 *SupportedLanguages; CHAR8 *PlatformLanguage; CHAR8 *BestLanguage; EFI_HII_HANDLE UefiHiiHandle; EFI_STATUS Status; Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This); Rfc4646AsciiLanguage = NULL; SupportedLanguages = NULL; PlatformLanguage = NULL; Status = EFI_SUCCESS; if (LanguageString != NULL) { Iso639AsciiLanguage = AllocateZeroPool (StrLen (LanguageString) + 1); if (Iso639AsciiLanguage == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr (LanguageString, Iso639AsciiLanguage); // // Caller of Framework HII Interface uses the Language Identification String defined // in Iso639. So map it to the Language Identifier defined in RFC4646. // Rfc4646AsciiLanguage = ConvertLanguagesIso639ToRfc4646 (Iso639AsciiLanguage); FreePool (Iso639AsciiLanguage); // // If Rfc4646AsciiLanguage is NULL, more language mapping must be added to // Iso639ToRfc4646Map. // ASSERT (Rfc4646AsciiLanguage != NULL); } UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle); if (UefiHiiHandle == NULL) { Status = EFI_NOT_FOUND; goto Done; } // // Get the languages that the package specified by HiiHandle supports // SupportedLanguages = HiiGetSupportedLanguages (UefiHiiHandle); if (SupportedLanguages == NULL) { goto Done; } // // Get the current platform language setting // PlatformLanguage = GetEfiGlobalVariable (L"PlatformLang"); // // Get the best matching language from SupportedLanguages // BestLanguage = GetBestLanguage ( SupportedLanguages, FALSE, // RFC 4646 mode (Rfc4646AsciiLanguage != NULL) ? Rfc4646AsciiLanguage : "", // Highest priority (PlatformLanguage != NULL) ? PlatformLanguage : "", // Next highest priority SupportedLanguages, // Lowest priority NULL ); if (BestLanguage != NULL) { Status = mHiiStringProtocol->GetString ( mHiiStringProtocol, BestLanguage, UefiHiiHandle, Token, StringBuffer, BufferLength, NULL ); FreePool (BestLanguage); } else { Status = EFI_INVALID_PARAMETER; } Done: if (Rfc4646AsciiLanguage != NULL) { FreePool (Rfc4646AsciiLanguage); } if (SupportedLanguages != NULL) { FreePool (SupportedLanguages); } if (PlatformLanguage != NULL) { FreePool (PlatformLanguage); } return Status; }
EFI_STATUS DefineDefaultBootEntries ( VOID ) { BDS_LOAD_OPTION* BdsLoadOption; UINTN Size; EFI_STATUS Status; EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol; EFI_DEVICE_PATH* BootDevicePath; UINT8* OptionalData; UINTN OptionalDataSize; ARM_BDS_LOADER_ARGUMENTS* BootArguments; ARM_BDS_LOADER_TYPE BootType; EFI_DEVICE_PATH* InitrdPath; UINTN InitrdSize; UINTN CmdLineSize; UINTN CmdLineAsciiSize; CHAR16* DefaultBootArgument; CHAR8* AsciiDefaultBootArgument; // // If Boot Order does not exist then create a default entry // Size = 0; Status = gRT->GetVariable (L"BootOrder", &gEfiGlobalVariableGuid, NULL, &Size, NULL); if (Status == EFI_NOT_FOUND) { if ((PcdGetPtr(PcdDefaultBootDevicePath) == NULL) || (StrLen ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)) == 0)) { return EFI_UNSUPPORTED; } Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); if (EFI_ERROR(Status)) { // You must provide an implementation of DevicePathFromTextProtocol in your firmware (eg: DevicePathDxe) DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathFromTextProtocol\n")); return Status; } BootDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)); DEBUG_CODE_BEGIN(); // We convert back to the text representation of the device Path to see if the initial text is correct EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; CHAR16* DevicePathTxt; Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); ASSERT_EFI_ERROR(Status); DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootDevicePath, TRUE, TRUE); ASSERT (StrCmp ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath), DevicePathTxt) == 0); FreePool (DevicePathTxt); DEBUG_CODE_END(); // Create the entry is the Default values are correct if (BootDevicePath != NULL) { BootType = (ARM_BDS_LOADER_TYPE)PcdGet32 (PcdDefaultBootType); // We do not support NULL pointer ASSERT (PcdGetPtr (PcdDefaultBootArgument) != NULL); // // Logic to handle ASCII or Unicode default parameters // if (*(CHAR8*)PcdGetPtr (PcdDefaultBootArgument) == '\0') { CmdLineSize = 0; CmdLineAsciiSize = 0; DefaultBootArgument = NULL; AsciiDefaultBootArgument = NULL; } else if (IsUnicodeString ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument))) { // The command line is a Unicode string DefaultBootArgument = (CHAR16*)PcdGetPtr (PcdDefaultBootArgument); CmdLineSize = StrSize (DefaultBootArgument); // Initialize ASCII variables CmdLineAsciiSize = CmdLineSize / 2; AsciiDefaultBootArgument = AllocatePool (CmdLineAsciiSize); if (AsciiDefaultBootArgument == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument), AsciiDefaultBootArgument); } else { // The command line is a ASCII string AsciiDefaultBootArgument = (CHAR8*)PcdGetPtr (PcdDefaultBootArgument); CmdLineAsciiSize = AsciiStrSize (AsciiDefaultBootArgument); // Initialize ASCII variables CmdLineSize = CmdLineAsciiSize * 2; DefaultBootArgument = AllocatePool (CmdLineSize); if (DefaultBootArgument == NULL) { return EFI_OUT_OF_RESOURCES; } AsciiStrToUnicodeStr (AsciiDefaultBootArgument, DefaultBootArgument); } if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) { InitrdPath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootInitrdPath)); InitrdSize = GetDevicePathSize (InitrdPath); OptionalDataSize = sizeof(ARM_BDS_LOADER_ARGUMENTS) + CmdLineAsciiSize + InitrdSize; BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)AllocatePool (OptionalDataSize); if (BootArguments == NULL) { return EFI_OUT_OF_RESOURCES; } BootArguments->LinuxArguments.CmdLineSize = CmdLineAsciiSize; BootArguments->LinuxArguments.InitrdSize = InitrdSize; CopyMem ((VOID*)(BootArguments + 1), AsciiDefaultBootArgument, CmdLineAsciiSize); CopyMem ((VOID*)((UINTN)(BootArguments + 1) + CmdLineAsciiSize), InitrdPath, InitrdSize); OptionalData = (UINT8*)BootArguments; } else { OptionalData = (UINT8*)DefaultBootArgument; OptionalDataSize = CmdLineSize; } BootOptionCreate (LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT, (CHAR16*)PcdGetPtr(PcdDefaultBootDescription), BootDevicePath, BootType, OptionalData, OptionalDataSize, &BdsLoadOption ); FreePool (BdsLoadOption); if (DefaultBootArgument == (CHAR16*)PcdGetPtr (PcdDefaultBootArgument)) { FreePool (AsciiDefaultBootArgument); } else if (DefaultBootArgument != NULL) { FreePool (DefaultBootArgument); } } else { Status = EFI_UNSUPPORTED; } } return Status; }
/** Publish the smbios type 1. @param Event Event whose notification function is being invoked (gEfiDxeSmmReadyToLockProtocolGuid). @param Context Pointer to the notification functions context, which is implementation dependent. @retval None **/ EFI_STATUS EFIAPI AddSmbiosManuCallback ( IN EFI_EVENT Event, IN VOID *Context ) { CHAR8 *OptionalStrStart; UINTN ManuStrLen; UINTN VerStrLen; UINTN PdNameStrLen; UINTN SerialNumStrLen; UINTN SkuNumberStrLen; UINTN FamilyNameStrLen; EFI_STATUS Status; EFI_STRING Manufacturer; EFI_STRING ProductName; EFI_STRING Version; EFI_STRING SerialNumber; EFI_STRING SkuNumber; EFI_STRING FamilyName; STRING_REF TokenToGet; EFI_SMBIOS_HANDLE SmbiosHandle; SMBIOS_TABLE_TYPE1 *SmbiosRecord; EFI_MISC_SYSTEM_MANUFACTURER *ForType1InputData; EFI_SMBIOS_PROTOCOL *Smbios; CHAR16 Buffer[40]; CHAR16 *MacStr; EFI_HANDLE *Handles; UINTN BufferSize; CHAR16 PlatformNameBuffer[40]; ForType1InputData = (EFI_MISC_SYSTEM_MANUFACTURER *)Context; // // First check for invalid parameters. // if (Context == NULL || mPlatformInfo == NULL) { return EFI_INVALID_PARAMETER; } Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID *) &Smbios); ASSERT_EFI_ERROR (Status); if (BOARD_ID_MINNOW2_COMPATIBLE == mPlatformInfo->BoardId) { // Detect the board is compatible board platform UnicodeSPrint (PlatformNameBuffer, sizeof (PlatformNameBuffer),L"%s",L"Minnowboard Compatible "); } else { UnicodeSPrint (PlatformNameBuffer, sizeof (PlatformNameBuffer),L"%s",L"Minnowboard Max "); } // // Silicon Steppings // switch (PchStepping()) { case PchA0: UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"A0 PLATFORM"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL); UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"A0"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL); DEBUG ((EFI_D_ERROR, "A0 Stepping Detected\n")); break; case PchA1: UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"A1 PLATFORM"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL); UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"A1"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL); DEBUG ((EFI_D_ERROR, "A1 Stepping Detected\n")); break; case PchB0: UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"B0 PLATFORM"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL); UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B0"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL); DEBUG ((EFI_D_ERROR, "B0 Stepping Detected\n")); break; case PchB1: UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"B1 PLATFORM"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL); UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B1"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL); DEBUG ((EFI_D_ERROR, "B1 Stepping Detected\n")); break; case PchB2: UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"B2 PLATFORM"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL); UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B2"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL); DEBUG ((EFI_D_ERROR, "B2 Stepping Detected\n")); break; case PchB3: UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"B3 PLATFORM"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL); UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B3"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL); DEBUG ((EFI_D_ERROR, "B3 Stepping Detected\n")); break; case PchC0: UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"C0 PLATFORM"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL); UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"C0"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL); DEBUG ((EFI_D_ERROR, "C0 Stepping Detected\n")); break; case PchD0: UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"D0 PLATFORM"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL); UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"D0"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL); DEBUG ((EFI_D_ERROR, "D0 Stepping Detected\n")); break; default: DEBUG ((EFI_D_ERROR, "Unknow Stepping Detected\n")); break; } if (BOARD_ID_MINNOW2_COMPATIBLE == mPlatformInfo->BoardId) { UnicodeSPrint (Buffer, sizeof (Buffer),L"Compatible Vendor"); HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_MANUFACTURER), Buffer, NULL); } TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER); Manufacturer = SmbiosMiscGetString (TokenToGet); ManuStrLen = StrLen(Manufacturer); if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) { return EFI_UNSUPPORTED; } TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME); ProductName = SmbiosMiscGetString (TokenToGet); PdNameStrLen = StrLen(ProductName); if (PdNameStrLen > SMBIOS_STRING_MAX_LENGTH) { return EFI_UNSUPPORTED; } TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_VERSION); Version = SmbiosMiscGetString (TokenToGet); VerStrLen = StrLen(Version); if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) { return EFI_UNSUPPORTED; } // //Get handle infomation // BufferSize = 0; Handles = NULL; Status = gBS->LocateHandle ( ByProtocol, &gEfiSimpleNetworkProtocolGuid, NULL, &BufferSize, Handles ); if (Status == EFI_BUFFER_TOO_SMALL) { Handles = AllocateZeroPool(BufferSize); if (Handles == NULL) { return (EFI_OUT_OF_RESOURCES); } Status = gBS->LocateHandle( ByProtocol, &gEfiSimpleNetworkProtocolGuid, NULL, &BufferSize, Handles ); } // //Get the MAC string // Status = NetLibGetMacString ( *Handles, NULL, &MacStr ); if (EFI_ERROR (Status)) { return Status; } SerialNumber = MacStr; SerialNumStrLen = StrLen(SerialNumber); if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) { return EFI_UNSUPPORTED; } TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SKU_NUMBER); SkuNumber = SmbiosMiscGetString (TokenToGet); SkuNumberStrLen = StrLen(SkuNumber); if (SkuNumberStrLen > SMBIOS_STRING_MAX_LENGTH) { return EFI_UNSUPPORTED; } TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_FAMILY_NAME1); FamilyName = SmbiosMiscGetString (TokenToGet); FamilyNameStrLen = StrLen(FamilyName); if (FamilyNameStrLen > SMBIOS_STRING_MAX_LENGTH) { return EFI_UNSUPPORTED; } // // Two zeros following the last string. // SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SkuNumberStrLen + 1 + FamilyNameStrLen + 1 + 1); ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SkuNumberStrLen + 1 + FamilyNameStrLen + 1 + 1); SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_INFORMATION; SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE1); // // Make handle chosen by smbios protocol.add automatically. // SmbiosRecord->Hdr.Handle = 0; // // Manu will be the 1st optional string following the formatted structure. // SmbiosRecord->Manufacturer = 1; // // ProductName will be the 2nd optional string following the formatted structure. // SmbiosRecord->ProductName = 2; // // Version will be the 3rd optional string following the formatted structure. // SmbiosRecord->Version = 3; // // Version will be the 4th optional string following the formatted structure. // SmbiosRecord->SerialNumber = 4; SmbiosRecord->SKUNumber= 5; SmbiosRecord->Family= 6; // // Unique UUID // ForType1InputData->SystemUuid.Data1 = PcdGet32 (PcdProductSerialNumber); ForType1InputData->SystemUuid.Data4[0] = PcdGet8 (PcdEmmcManufacturerId); CopyMem ((UINT8 *) (&SmbiosRecord->Uuid),&ForType1InputData->SystemUuid,16); SmbiosRecord->WakeUpType = (UINT8)ForType1InputData->SystemWakeupType; OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1); UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart); UnicodeStrToAsciiStr(ProductName, OptionalStrStart + ManuStrLen + 1); UnicodeStrToAsciiStr(Version, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1); UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1); UnicodeStrToAsciiStr(SkuNumber, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1); UnicodeStrToAsciiStr(FamilyName, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SkuNumberStrLen +1); // // Now we have got the full smbios record, call smbios protocol to add this record. // SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; Status = Smbios-> Add( Smbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord ); FreePool(SmbiosRecord); return Status; }
/** This function is called to provide results data to the driver. This data consists of a unique key that is used to identify which data is either being passed back or being asked for. @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param[in] Action Specifies the type of action taken by the browser. @param[in] QuestionId A unique value which is sent to the original exporting driver so that it can identify the type of data to expect. The format of the data tends to vary based on the opcode that enerated the callback. @param[in] Type The type of value for the question. @param[in] Value A pointer to the data being sent to the original exporting driver. @param[out] ActionRequest On return, points to the action requested by the callback function. @retval EFI_SUCCESS The callback successfully handled the action. @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. @retval EFI_DEVICE_ERROR The variable could not be saved. @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.Currently not implemented. @retval EFI_INVALID_PARAMETERS Passing in wrong parameter. @retval Others Other errors as indicated. **/ EFI_STATUS EFIAPI Ip4FormCallback ( 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 ) { IP4_CONFIG_INSTANCE *Ip4ConfigInstance; CHAR8 Ip4String[IP4_STR_MAX_SIZE]; IP4_CONFIG_IFR_NVDATA *IfrFormNvData; EFI_IP_ADDRESS HostIp; EFI_IP_ADDRESS SubnetMask; EFI_IP_ADDRESS Gateway; EFI_STATUS Status; EFI_INPUT_KEY Key; Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This); IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA)); if (IfrFormNvData == NULL) { return EFI_OUT_OF_RESOURCES; } // // Retrive uncommitted data from Browser // if (!HiiGetBrowserData (&mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData)) { FreePool (IfrFormNvData); return EFI_NOT_FOUND; } Status = EFI_SUCCESS; switch (QuestionId) { case KEY_ENABLE: if (IfrFormNvData->Configure == 0) { Ip4ConfigInstance->Ip4ConfigCallbackInfo.Configured = FALSE; } else { Ip4ConfigInstance->Ip4ConfigCallbackInfo.Configured = TRUE; } break; case KEY_DHCP_ENABLE: if (IfrFormNvData->DhcpEnable == 0) { Ip4ConfigInstance->Ip4ConfigCallbackInfo.DhcpEnabled = FALSE; } else { Ip4ConfigInstance->Ip4ConfigCallbackInfo.DhcpEnabled = TRUE; } break; case KEY_LOCAL_IP: UnicodeStrToAsciiStr (IfrFormNvData->StationAddress, Ip4String); Status = Ip4AsciiStrToIp (Ip4String, &HostIp.v4); if (EFI_ERROR (Status) || !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL); Status = EFI_INVALID_PARAMETER; } else { CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, &HostIp.v4, sizeof (HostIp.v4)); } break; case KEY_SUBNET_MASK: UnicodeStrToAsciiStr (IfrFormNvData->SubnetMask, Ip4String); Status = Ip4AsciiStrToIp (Ip4String, &SubnetMask.v4); if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid SubnetMask!", NULL); Status = EFI_INVALID_PARAMETER; } else { CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4)); } break; case KEY_GATE_WAY: UnicodeStrToAsciiStr (IfrFormNvData->GatewayAddress, Ip4String); Status = Ip4AsciiStrToIp (Ip4String, &Gateway.v4); if (EFI_ERROR (Status) || ((Gateway.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), 0))) { CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL); Status = EFI_INVALID_PARAMETER; } else { CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, &Gateway.v4, sizeof (Gateway.v4)); } break; case KEY_SAVE_CHANGES: Status = Ip4ConfigConvertIfrNvDataToDeviceConfigData (Ip4ConfigInstance); *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; break; default: break; } if (!EFI_ERROR (Status)) { // // Pass changed uncommitted data back to Form Browser // HiiSetBrowserData (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData, NULL); } FreePool (IfrFormNvData); return Status; }
/** Dump performance data. @param[in] ImageHandle The image handle. @param[in] SystemTable The system table. @retval EFI_SUCCESS Command completed successfully. @retval EFI_INVALID_PARAMETER Command usage error. @retval EFI_ABORTED The user aborts the operation. @retval value Unknown error. **/ EFI_STATUS EFIAPI InitializeDp ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { UINT64 Freq; UINT64 Ticker; UINT32 ListIndex; LIST_ENTRY *ParamPackage; CONST CHAR16 *CmdLineArg; EFI_STRING StringPtr; UINTN Number2Display; EFI_STATUS Status; BOOLEAN SummaryMode; BOOLEAN VerboseMode; BOOLEAN AllMode; BOOLEAN RawMode; BOOLEAN TraceMode; BOOLEAN ProfileMode; BOOLEAN ExcludeMode; BOOLEAN CumulativeMode; CONST CHAR16 *CustomCumulativeToken; PERF_CUM_DATA *CustomCumulativeData; EFI_STRING StringDpOptionQh; EFI_STRING StringDpOptionLh; EFI_STRING StringDpOptionUh; EFI_STRING StringDpOptionLv; EFI_STRING StringDpOptionUs; EFI_STRING StringDpOptionLs; EFI_STRING StringDpOptionUa; EFI_STRING StringDpOptionUr; EFI_STRING StringDpOptionUt; EFI_STRING StringDpOptionUp; EFI_STRING StringDpOptionLx; EFI_STRING StringDpOptionLn; EFI_STRING StringDpOptionLt; EFI_STRING StringDpOptionLi; EFI_STRING StringDpOptionLc; SummaryMode = FALSE; VerboseMode = FALSE; AllMode = FALSE; RawMode = FALSE; TraceMode = FALSE; ProfileMode = FALSE; ExcludeMode = FALSE; CumulativeMode = FALSE; CustomCumulativeData = NULL; StringDpOptionQh = NULL; StringDpOptionLh = NULL; StringDpOptionUh = NULL; StringDpOptionLv = NULL; StringDpOptionUs = NULL; StringDpOptionLs = NULL; StringDpOptionUa = NULL; StringDpOptionUr = NULL; StringDpOptionUt = NULL; StringDpOptionUp = NULL; StringDpOptionLx = NULL; StringDpOptionLn = NULL; StringDpOptionLt = NULL; StringDpOptionLi = NULL; StringDpOptionLc = NULL; StringPtr = NULL; // Get DP's entry time as soon as possible. // This is used as the Shell-Phase end time. // Ticker = GetPerformanceCounter (); // Register our string package with HII and return the handle to it. // gHiiHandle = HiiAddPackages (&gEfiCallerIdGuid, ImageHandle, DPStrings, NULL); ASSERT (gHiiHandle != NULL); // Initial the command list // InitialShellParamList (); /**************************************************************************** **** Process Command Line arguments **** ****************************************************************************/ Status = ShellCommandLineParse (DpParamList, &ParamPackage, NULL, TRUE); if (EFI_ERROR(Status)) { PrintToken (STRING_TOKEN (STR_DP_INVALID_ARG)); ShowHelp(); } else { StringDpOptionQh = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_QH), NULL); StringDpOptionLh = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LH), NULL); StringDpOptionUh = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UH), NULL); if (ShellCommandLineGetFlag (ParamPackage, StringDpOptionQh) || ShellCommandLineGetFlag (ParamPackage, StringDpOptionLh) || ShellCommandLineGetFlag (ParamPackage, StringDpOptionUh)) { ShowHelp(); } else { StringDpOptionLv = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LV), NULL); StringDpOptionUs = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_US), NULL); StringDpOptionLs = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LS), NULL); StringDpOptionUa = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UA), NULL); StringDpOptionUr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UR), NULL); StringDpOptionUt = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UT), NULL); StringDpOptionUp = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UP), NULL); StringDpOptionLx = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LX), NULL); StringDpOptionLn = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LN), NULL); StringDpOptionLt = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LT), NULL); StringDpOptionLi = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LI), NULL); StringDpOptionLc = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LC), NULL); // Boolean Options // VerboseMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionLv); SummaryMode = (BOOLEAN) (ShellCommandLineGetFlag (ParamPackage, StringDpOptionUs) || ShellCommandLineGetFlag (ParamPackage, StringDpOptionLs)); AllMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionUa); RawMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionUr); #if PROFILING_IMPLEMENTED TraceMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionUt); ProfileMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionUp); #endif // PROFILING_IMPLEMENTED ExcludeMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionLx); mShowId = ShellCommandLineGetFlag (ParamPackage, StringDpOptionLi); CumulativeMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionLc); // Options with Values CmdLineArg = ShellCommandLineGetValue (ParamPackage, StringDpOptionLn); if (CmdLineArg == NULL) { Number2Display = DEFAULT_DISPLAYCOUNT; } else { Number2Display = StrDecimalToUintn(CmdLineArg); if (Number2Display == 0) { Number2Display = MAXIMUM_DISPLAYCOUNT; } } CmdLineArg = ShellCommandLineGetValue (ParamPackage, StringDpOptionLt); if (CmdLineArg == NULL) { mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us } else { mInterestThreshold = StrDecimalToUint64(CmdLineArg); } // Handle Flag combinations and default behaviors // If both TraceMode and ProfileMode are FALSE, set them both to TRUE if ((! TraceMode) && (! ProfileMode)) { TraceMode = TRUE; #if PROFILING_IMPLEMENTED ProfileMode = TRUE; #endif // PROFILING_IMPLEMENTED } // // Init the custom cumulative data. // CustomCumulativeToken = ShellCommandLineGetValue (ParamPackage, StringDpOptionLc); if (CustomCumulativeToken != NULL) { CustomCumulativeData = AllocateZeroPool (sizeof (PERF_CUM_DATA)); ASSERT (CustomCumulativeData != NULL); CustomCumulativeData->MinDur = 0; CustomCumulativeData->MaxDur = 0; CustomCumulativeData->Count = 0; CustomCumulativeData->Duration = 0; CustomCumulativeData->Name = AllocateZeroPool (StrLen (CustomCumulativeToken) + 1); UnicodeStrToAsciiStr (CustomCumulativeToken, CustomCumulativeData->Name); } /**************************************************************************** **** Timer specific processing **** ****************************************************************************/ // Get the Performance counter characteristics: // Freq = Frequency in Hz // StartCount = Value loaded into the counter when it starts counting // EndCount = Value counter counts to before it needs to be reset // Freq = GetPerformanceCounterProperties (&TimerInfo.StartCount, &TimerInfo.EndCount); // Convert the Frequency from Hz to KHz TimerInfo.Frequency = (UINT32)DivU64x32 (Freq, 1000); // Determine in which direction the performance counter counts. TimerInfo.CountUp = (BOOLEAN) (TimerInfo.EndCount >= TimerInfo.StartCount); /**************************************************************************** **** Print heading **** ****************************************************************************/ // print DP's build version PrintToken (STRING_TOKEN (STR_DP_BUILD_REVISION), DP_MAJOR_VERSION, DP_MINOR_VERSION); // print performance timer characteristics PrintToken (STRING_TOKEN (STR_DP_KHZ), TimerInfo.Frequency); // Print Timer frequency in KHz if ((VerboseMode) && (! RawMode) ) { StringPtr = HiiGetString (gHiiHandle, (EFI_STRING_ID) (TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)), NULL); ASSERT (StringPtr != NULL); PrintToken (STRING_TOKEN (STR_DP_TIMER_PROPERTIES), // Print Timer count range and direction StringPtr, TimerInfo.StartCount, TimerInfo.EndCount ); PrintToken (STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), mInterestThreshold); } /* ************************************************************************** **** Print Sections based on command line options **** **** Option modes have the following priority: **** v Verbose -- Valid in combination with any other options **** t Threshold -- Modifies All, Raw, and Cooked output **** Default is 0 for All and Raw mode **** Default is DEFAULT_THRESHOLD for "Cooked" mode **** n Number2Display Used by All and Raw mode. Otherwise ignored. **** A All -- R and S options are ignored **** R Raw -- S option is ignored **** s Summary -- Modifies "Cooked" output only **** Cooked (Default) **** **** The All, Raw, and Cooked modes are modified by the Trace and Profile **** options. **** !T && !P := (0) Default, Both are displayed **** T && !P := (1) Only Trace records are displayed **** !T && P := (2) Only Profile records are displayed **** T && P := (3) Same as Default, both are displayed ****************************************************************************/ GatherStatistics (CustomCumulativeData); if (CumulativeMode) { ProcessCumulative (CustomCumulativeData); } else if (AllMode) { if (TraceMode) { Status = DumpAllTrace( Number2Display, ExcludeMode); if (Status == EFI_ABORTED) { goto Done; } } if (ProfileMode) { DumpAllProfile( Number2Display, ExcludeMode); } } else if (RawMode) { if (TraceMode) { Status = DumpRawTrace( Number2Display, ExcludeMode); if (Status == EFI_ABORTED) { goto Done; } } if (ProfileMode) { DumpRawProfile( Number2Display, ExcludeMode); } } else { //------------- Begin Cooked Mode Processing if (TraceMode) { ProcessPhases ( Ticker ); if ( ! SummaryMode) { Status = ProcessHandles ( ExcludeMode); if (Status == EFI_ABORTED) { goto Done; } Status = ProcessPeims (); if (Status == EFI_ABORTED) { goto Done; } Status = ProcessGlobal (); if (Status == EFI_ABORTED) { goto Done; } ProcessCumulative (NULL); } } if (ProfileMode) { DumpAllProfile( Number2Display, ExcludeMode); } } //------------- End of Cooked Mode Processing if ( VerboseMode || SummaryMode) { DumpStatistics(); } } } Done: // // Free the memory allocate from HiiGetString // ListIndex = 0; while (DpParamList[ListIndex].Name != NULL) { FreePool (DpParamList[ListIndex].Name); ListIndex ++; } FreePool (DpParamList); SafeFreePool (StringDpOptionQh); SafeFreePool (StringDpOptionLh); SafeFreePool (StringDpOptionUh); SafeFreePool (StringDpOptionLv); SafeFreePool (StringDpOptionUs); SafeFreePool (StringDpOptionLs); SafeFreePool (StringDpOptionUa); SafeFreePool (StringDpOptionUr); SafeFreePool (StringDpOptionUt); SafeFreePool (StringDpOptionUp); SafeFreePool (StringDpOptionLx); SafeFreePool (StringDpOptionLn); SafeFreePool (StringDpOptionLt); SafeFreePool (StringDpOptionLi); SafeFreePool (StringDpOptionLc); SafeFreePool (StringPtr); SafeFreePool (mPrintTokenBuffer); if (CustomCumulativeData != NULL) { SafeFreePool (CustomCumulativeData->Name); } SafeFreePool (CustomCumulativeData); HiiRemovePackages (gHiiHandle); return Status; }
EFI_STATUS FileOpen ( IN EFI_FILE *File, OUT EFI_FILE **NewHandle, IN CHAR16 *FileName, IN UINT64 OpenMode, IN UINT64 Attributes ) { SEMIHOST_FCB *FileFcb = NULL; EFI_STATUS Status = EFI_SUCCESS; UINTN SemihostHandle; CHAR8 *AsciiFileName; UINT32 SemihostMode; BOOLEAN IsRoot; if ((FileName == NULL) || (NewHandle == NULL)) { return EFI_INVALID_PARAMETER; } // Semihost interface requires ASCII filenames AsciiFileName = AllocatePool ((StrLen (FileName) + 1) * sizeof (CHAR8)); if (AsciiFileName == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr (FileName, AsciiFileName); if ((AsciiStrCmp (AsciiFileName, "\\") == 0) || (AsciiStrCmp (AsciiFileName, "/") == 0) || (AsciiStrCmp (AsciiFileName, "") == 0) || (AsciiStrCmp (AsciiFileName, ".") == 0)) { // Opening '/', '\', '.', or the NULL pathname is trying to open the root directory IsRoot = TRUE; // Root directory node doesn't have a name. FreePool (AsciiFileName); AsciiFileName = NULL; } else { // Translate EFI_FILE_MODE into Semihosting mode if (OpenMode & EFI_FILE_MODE_WRITE) { SemihostMode = SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY; } else if (OpenMode & EFI_FILE_MODE_READ) { SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY; } else { return EFI_UNSUPPORTED; } // Add the creation flag if necessary if (OpenMode & EFI_FILE_MODE_CREATE) { SemihostMode |= SEMIHOST_FILE_MODE_CREATE; } // Call the semihosting interface to open the file. Status = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle); if (EFI_ERROR(Status)) { return Status; } IsRoot = FALSE; } // Allocate a control block and fill it FileFcb = AllocateFCB (); if (FileFcb == NULL) { return EFI_OUT_OF_RESOURCES; } FileFcb->FileName = AsciiFileName; FileFcb->SemihostHandle = SemihostHandle; FileFcb->Position = 0; FileFcb->IsRoot = IsRoot; InsertTailList (&gFileList, &FileFcb->Link); *NewHandle = &FileFcb->File; return Status; }
/** Fill a standard Smbios string field. This function will convert the unicode string to single byte chars, and only English language is supported. This function changes the Structure pointer value of the structure node, which should be noted by Caller. @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed. @param Offset Offset of SMBIOS record which RecordData will be filled. @param RecordData RecordData buffer will be filled. @param RecordDataSize The size of RecordData buffer. @retval EFI_INVALID_PARAMETER RecordDataSize is too larger @retval EFI_OUT_OF_RESOURCES No memory to allocate new buffer for string @retval EFI_SUCCESS Sucess append string for a SMBIOS record. **/ EFI_STATUS SmbiosFldString ( IN OUT SMBIOS_STRUCTURE_NODE *StructureNode, IN UINT32 Offset, IN VOID *RecordData, IN UINT32 RecordDataSize ) { EFI_STATUS Status; UINT16 *Data; CHAR8 AsciiData[SMBIOS_STRING_MAX_LENGTH]; UINT8 CountOfStrings; UINTN OrigStringNumber; EFI_SMBIOS_PROTOCOL *Smbios; EFI_SMBIOS_HANDLE SmbiosHandle; UINT32 OrigStructureSize; UINTN NewStructureSize; EFI_SMBIOS_TABLE_HEADER *NewRecord; UINT32 StringLength; Status = EFI_SUCCESS; OrigStringNumber = 0; OrigStructureSize = 0; // // if we have a NULL token, // if (0 == *((STRING_REF *) RecordData)) { *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = 0; return EFI_SUCCESS; } // // Get the String from the Hii Database // Data = HiiGetPackageString ( &(StructureNode->ProducerName), *((EFI_STRING_ID *) RecordData), NULL ); if (Data == NULL) { return EFI_INVALID_PARAMETER; } StringLength = (UINT32)StrLen (Data); // // Count the string size including the terminating 0. // if (StringLength == 0) { *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = 0; FreePool (Data); return EFI_SUCCESS; } if (StringLength > SMBIOS_STRING_MAX_LENGTH) { // // Too long a string // FreePool (Data); return EFI_INVALID_PARAMETER; } Smbios = GetSmbiosProtocol(); ASSERT (Smbios != NULL); // // Convert Unicode string to Ascii string which only supported by SMBIOS. // ZeroMem (AsciiData, SMBIOS_STRING_MAX_LENGTH); UnicodeStrToAsciiStr (Data, AsciiData); // // if the field at offset is already filled with some value, // find out the string it points to // OrigStringNumber = *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset); if (OrigStringNumber != 0) { DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Update %dth string for type[%d],offset[0x%x],handle[0x%x] to [%s]\n", OrigStringNumber, StructureNode->SmbiosType, Offset, StructureNode->SmbiosHandle, AsciiData)); // // If original string number is not zero, just update string // Status = Smbios->UpdateString (Smbios, &StructureNode->SmbiosHandle, &OrigStringNumber, AsciiData); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Fail to update %dth string in offset 0x%x for handle:0x%x type:0x%x\n", OrigStringNumber, Offset, StructureNode->SmbiosHandle, StructureNode->SmbiosType)); ASSERT_EFI_ERROR (Status); return Status; } } else { // // If the string has not been filled in SMBIOS database, remove it and add again // with string appended. // Status = GetSmbiosStructureSize (StructureNode->Structure, &OrigStructureSize, &CountOfStrings); ASSERT_EFI_ERROR (Status); if (CountOfStrings == 0) { NewStructureSize = OrigStructureSize + StringLength; } else { NewStructureSize = OrigStructureSize + StringLength + 1; } NewRecord = AllocateZeroPool (NewStructureSize); if (NewRecord == NULL) { return EFI_OUT_OF_RESOURCES; } CopyMem (NewRecord, StructureNode->Structure, OrigStructureSize); // // Copy new string into tail of original SMBIOS record buffer. // if (CountOfStrings == 0) { AsciiStrCpy ((CHAR8 *)NewRecord + OrigStructureSize - 2, AsciiData); } else { AsciiStrCpy ((CHAR8 *)NewRecord + OrigStructureSize - 1, AsciiData); } DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Type(%d) offset(0x%x) StringNumber:%d\n", StructureNode->SmbiosType, Offset, CountOfStrings + 1)); // // Update string reference number // *(UINT8 *) ((UINT8 *) NewRecord + Offset) = (UINT8) (CountOfStrings + 1); SmbiosHandle = StructureNode->SmbiosHandle; // // Remove original SMBIOS record and add new one // Status = Smbios->Remove (Smbios, StructureNode->SmbiosHandle); ASSERT_EFI_ERROR (Status); // // Add new SMBIOS record // Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, NewRecord); ASSERT_EFI_ERROR (Status); StructureNode->SmbiosHandle = SmbiosHandle; FreePool (NewRecord); } // // The SMBIOS record buffer maybe re-allocated in SMBIOS database, // so update cached buffer pointer in DataHub structure list. // StructureNode->Structure = GetSmbiosBufferFromHandle ( StructureNode->SmbiosHandle, StructureNode->SmbiosType, NULL ); ASSERT (StructureNode->Structure != NULL); // // The string update action maybe lead the record is re-allocated in SMBIOS database // so update cached record pointer // Status = GetSmbiosStructureSize (StructureNode->Structure, &StructureNode->StructureSize, &CountOfStrings); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }
/** The Request() function queues an HTTP request to this HTTP instance. Similar to Transmit() function in the EFI TCP driver. When the HTTP request is sent successfully, or if there is an error, Status in token will be updated and Event will be signaled. @param[in] This Pointer to EFI_HTTP_PROTOCOL instance. @param[in] Token Pointer to storage containing HTTP request token. @retval EFI_SUCCESS Outgoing data was processed. @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_TIMEOUT Data was dropped out of the transmit or receive queue. @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources. @retval EFI_UNSUPPORTED The HTTP method is not supported in current implementation. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: This is NULL. Token->Message is NULL. Token->Message->Body is not NULL, Token->Message->BodyLength is non-zero, and Token->Message->Data is NULL, but a previous call to Request()has not been completed successfully. **/ EFI_STATUS EFIAPI EfiHttpRequest ( IN EFI_HTTP_PROTOCOL *This, IN EFI_HTTP_TOKEN *Token ) { EFI_HTTP_MESSAGE *HttpMsg; EFI_HTTP_REQUEST_DATA *Request; VOID *UrlParser; EFI_STATUS Status; CHAR8 *HostName; UINT16 RemotePort; HTTP_PROTOCOL *HttpInstance; BOOLEAN Configure; BOOLEAN ReConfigure; CHAR8 *RequestStr; CHAR8 *Url; CHAR16 *HostNameStr; HTTP_TOKEN_WRAP *Wrap; HTTP_TCP_TOKEN_WRAP *TcpWrap; if ((This == NULL) || (Token == NULL)) { return EFI_INVALID_PARAMETER; } HttpMsg = Token->Message; if ((HttpMsg == NULL) || (HttpMsg->Headers == NULL)) { return EFI_INVALID_PARAMETER; } // // Current implementation does not support POST/PUT method. // If future version supports these two methods, Request could be NULL for a special case that to send large amounts // of data. For this case, the implementation need check whether previous call to Request() has been completed or not. // // Request = HttpMsg->Data.Request; if ((Request == NULL) || (Request->Url == NULL)) { return EFI_INVALID_PARAMETER; } // // Only support GET and HEAD method in current implementation. // if ((Request->Method != HttpMethodGet) && (Request->Method != HttpMethodHead)) { return EFI_UNSUPPORTED; } HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This); ASSERT (HttpInstance != NULL); if (HttpInstance->State < HTTP_STATE_HTTP_CONFIGED) { return EFI_NOT_STARTED; } if (HttpInstance->LocalAddressIsIPv6) { return EFI_UNSUPPORTED; } // // Check whether the token already existed. // if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTokenExist, Token))) { return EFI_ACCESS_DENIED; } Url = NULL; HostName = NULL; Wrap = NULL; HostNameStr = NULL; TcpWrap = NULL; // // Parse the URI of the remote host. // Url = AllocatePool (StrLen (Request->Url) + 1); if (Url == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr (Request->Url, Url); UrlParser = NULL; Status = HttpParseUrl (Url, (UINT32) AsciiStrLen (Url), FALSE, &UrlParser); if (EFI_ERROR (Status)) { goto Error1; } RequestStr = NULL; HostName = NULL; Status = HttpUrlGetHostName (Url, UrlParser, &HostName); if (EFI_ERROR (Status)) { goto Error1; } Status = HttpUrlGetPort (Url, UrlParser, &RemotePort); if (EFI_ERROR (Status)) { RemotePort = HTTP_DEFAULT_PORT; } Configure = TRUE; ReConfigure = TRUE; if (HttpInstance->RemoteHost == NULL && HttpInstance->RemotePort == 0) { // // Request() is called the first time. // ReConfigure = FALSE; } else { if ((HttpInstance->RemotePort == RemotePort) && (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0)) { // // Host Name and port number of the request URL are the same with previous call to Request(). // Check whether previous TCP packet sent out. // if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTcpNotReady, NULL))) { // // Wrap the HTTP token in HTTP_TOKEN_WRAP // Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP)); if (Wrap == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error1; } Wrap->HttpToken = Token; Wrap->HttpInstance = HttpInstance; Status = HttpCreateTcp4TxEvent (Wrap); if (EFI_ERROR (Status)) { goto Error1; } Status = NetMapInsertTail (&HttpInstance->TxTokens, Token, Wrap); if (EFI_ERROR (Status)) { goto Error1; } Wrap->TcpWrap.Method = Request->Method; FreePool (Url); FreePool (HostName); // // Queue the HTTP token and return. // return EFI_SUCCESS; } else { // // Use existing TCP instance to transmit the packet. // Configure = FALSE; ReConfigure = FALSE; } } else { // // Need close existing TCP instance and create a new TCP instance for data transmit. // if (HttpInstance->RemoteHost != NULL) { FreePool (HttpInstance->RemoteHost); HttpInstance->RemoteHost = NULL; } } } if (Configure) { // // Parse Url for IPv4 address, if failed, perform DNS resolution. // Status = NetLibAsciiStrToIp4 (HostName, &HttpInstance->RemoteAddr); if (EFI_ERROR (Status)) { HostNameStr = AllocateZeroPool ((AsciiStrLen (HostName) + 1) * sizeof (UINT16)); if (HostNameStr == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error1; } AsciiStrToUnicodeStr (HostName, HostNameStr); Status = HttpDns4 (HttpInstance, HostNameStr, &HttpInstance->RemoteAddr); FreePool (HostNameStr); if (EFI_ERROR (Status)) { goto Error1; } } // // Save the RemotePort and RemoteHost. // ASSERT (HttpInstance->RemoteHost == NULL); HttpInstance->RemotePort = RemotePort; HttpInstance->RemoteHost = HostName; HostName = NULL; } if (ReConfigure) { // // The request URL is different from previous calls to Request(), close existing TCP instance. // ASSERT (HttpInstance->Tcp4 != NULL); HttpCloseConnection (HttpInstance); EfiHttpCancel (This, NULL); } // // Wrap the HTTP token in HTTP_TOKEN_WRAP // Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP)); if (Wrap == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error1; } Wrap->HttpToken = Token; Wrap->HttpInstance = HttpInstance; Wrap->TcpWrap.Method = Request->Method; if (Configure) { // // Configure TCP instance. // Status = HttpConfigureTcp4 (HttpInstance, Wrap); if (EFI_ERROR (Status)) { goto Error1; } // // Connect TCP. // Status = HttpConnectTcp4 (HttpInstance); if (EFI_ERROR (Status)) { goto Error2; } } else { // // For the new HTTP token, create TX TCP token events. // Status = HttpCreateTcp4TxEvent (Wrap); if (EFI_ERROR (Status)) { goto Error1; } } // // Create request message. // RequestStr = HttpGenRequestString (HttpInstance, HttpMsg, Url); if (RequestStr == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error3; } Status = NetMapInsertTail (&HttpInstance->TxTokens, Token, Wrap); if (EFI_ERROR (Status)) { goto Error4; } FreePool (Url); if (HostName != NULL) { FreePool (HostName); } // // Transmit the request message. // Status = HttpTransmitTcp4 ( HttpInstance, Wrap, (UINT8*) RequestStr, AsciiStrLen (RequestStr) ); if (EFI_ERROR (Status)) { goto Error5; } return EFI_SUCCESS; Error5: NetMapRemoveTail (&HttpInstance->TxTokens, NULL); Error4: if (RequestStr != NULL) { FreePool (RequestStr); } Error3: HttpCloseConnection (HttpInstance); Error2: HttpCloseTcp4ConnCloseEvent (HttpInstance); if (NULL != Wrap->TcpWrap.TxToken.CompletionToken.Event) { gBS->CloseEvent (Wrap->TcpWrap.TxToken.CompletionToken.Event); } Error1: if (Url != NULL) { FreePool (Url); } if (HostName != NULL) { FreePool (HostName); } if (Wrap != NULL) { FreePool (Wrap); } if (UrlParser!= NULL) { HttpUrlFreeParser (UrlParser); } return Status; }
/** Internal work function to fill in EFI_OPEN_FILE information for the FV @param File Open file handle @param FileName Name of file after device stripped off **/ EFI_STATUS EblFvFileDevicePath ( IN OUT EFI_OPEN_FILE *File, IN CHAR8 *FileName, IN CONST UINT64 OpenMode ) { EFI_STATUS Status; EFI_STATUS GetNextFileStatus; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH DevicePathNode; EFI_DEVICE_PATH_PROTOCOL *DevicePath; UINTN Key; UINT32 AuthenticationStatus; CHAR8 AsciiSection[MAX_PATHNAME]; VOID *Section; UINTN SectionSize; EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; EFI_LBA Lba; UINTN BlockSize; UINTN NumberOfBlocks; EFI_FIRMWARE_VOLUME_HEADER *FvHeader = NULL; UINTN Index; Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&File->Fv); if (EFI_ERROR (Status)) { return Status; } // Get FVB Info about the handle Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb); if (!EFI_ERROR (Status)) { Status = Fvb->GetPhysicalAddress (Fvb, &File->FvStart); if (!EFI_ERROR (Status)) { FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)File->FvStart; File->FvHeaderSize = sizeof (EFI_FIRMWARE_VOLUME_HEADER); for (Index = 0; FvHeader->BlockMap[Index].Length !=0; Index++) { File->FvHeaderSize += sizeof (EFI_FV_BLOCK_MAP_ENTRY); } for (Lba = 0, File->FvSize = 0, NumberOfBlocks = 0; ; File->FvSize += (BlockSize * NumberOfBlocks), Lba += NumberOfBlocks) { Status = Fvb->GetBlockSize (Fvb, Lba, &BlockSize, &NumberOfBlocks); if (EFI_ERROR (Status)) { break; } } } } DevicePath = DevicePathFromHandle (File->EfiHandle); if (*FileName == '\0') { File->DevicePath = DuplicateDevicePath (DevicePath); File->Size = File->FvSize; File->MaxPosition = File->Size; } else { Key = 0; do { File->FvType = EFI_FV_FILETYPE_ALL; GetNextFileStatus = File->Fv->GetNextFile ( File->Fv, &Key, &File->FvType, &File->FvNameGuid, &File->FvAttributes, &File->Size ); if (!EFI_ERROR (GetNextFileStatus)) { // Compare GUID first Status = CompareGuidToString (&File->FvNameGuid, FileName); if (!EFI_ERROR(Status)) { break; } Section = NULL; Status = File->Fv->ReadSection ( File->Fv, &File->FvNameGuid, EFI_SECTION_USER_INTERFACE, 0, &Section, &SectionSize, &AuthenticationStatus ); if (!EFI_ERROR (Status)) { UnicodeStrToAsciiStr (Section, AsciiSection); if (AsciiStriCmp (FileName, AsciiSection) == 0) { FreePool (Section); break; } FreePool (Section); } } } while (!EFI_ERROR (GetNextFileStatus)); if (EFI_ERROR (GetNextFileStatus)) { return GetNextFileStatus; } if (OpenMode != EFI_SECTION_ALL) { // Calculate the size of the section we are targeting Section = NULL; File->Size = 0; Status = File->Fv->ReadSection ( File->Fv, &File->FvNameGuid, (EFI_SECTION_TYPE)OpenMode, 0, &Section, &File->Size, &AuthenticationStatus ); if (EFI_ERROR (Status)) { return Status; } } File->MaxPosition = File->Size; EfiInitializeFwVolDevicepathNode (&DevicePathNode, &File->FvNameGuid); File->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&DevicePathNode); } // FVB not required if FV was soft loaded... return EFI_SUCCESS; }
/** Open a file on the host system by means of the semihosting interface. @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to source location. @param[out] NewHandle A pointer to the location to return the opened handle for the new file. @param[in] FileName The Null-terminated string of the name of the file to be opened. @param[in] OpenMode The mode to open the file : Read or Read/Write or Read/Write/Create @param[in] Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the attribute bits for the newly created file. The mnemonics of the attribute bits are : EFI_FILE_READ_ONLY, EFI_FILE_HIDDEN, EFI_FILE_SYSTEM, EFI_FILE_RESERVED, EFI_FILE_DIRECTORY and EFI_FILE_ARCHIVE. @retval EFI_SUCCESS The file was open. @retval EFI_NOT_FOUND The specified file could not be found. @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed. @retval EFI_WRITE_PROTECTED Attempt to create a directory. This is not possible with the semi-hosting interface. @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid. **/ EFI_STATUS FileOpen ( IN EFI_FILE *This, OUT EFI_FILE **NewHandle, IN CHAR16 *FileName, IN UINT64 OpenMode, IN UINT64 Attributes ) { SEMIHOST_FCB *FileFcb; RETURN_STATUS Return; EFI_STATUS Status; UINTN SemihostHandle; CHAR8 *AsciiFileName; UINT32 SemihostMode; UINTN Length; if ((FileName == NULL) || (NewHandle == NULL)) { return EFI_INVALID_PARAMETER; } if ( (OpenMode != EFI_FILE_MODE_READ) && (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) && (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)) ) { return EFI_INVALID_PARAMETER; } if ((OpenMode & EFI_FILE_MODE_CREATE) && (Attributes & EFI_FILE_DIRECTORY) ) { return EFI_WRITE_PROTECTED; } AsciiFileName = AllocatePool (StrLen (FileName) + 1); if (AsciiFileName == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr (FileName, AsciiFileName); // Opening '/', '\', '.', or the NULL pathname is trying to open the root directory if ((AsciiStrCmp (AsciiFileName, "\\") == 0) || (AsciiStrCmp (AsciiFileName, "/") == 0) || (AsciiStrCmp (AsciiFileName, "") == 0) || (AsciiStrCmp (AsciiFileName, ".") == 0) ) { FreePool (AsciiFileName); return (VolumeOpen (&gSemihostFs, NewHandle)); } // // No control is done here concerning the file path. It is passed // as it is to the host operating system through the semi-hosting // interface. We first try to open the file in the read or update // mode even if the file creation has been asked for. That way, if // the file already exists, it is not truncated to zero length. In // write mode (bit SEMIHOST_FILE_MODE_WRITE up), if the file already // exists, it is reset to an empty file. // if (OpenMode == EFI_FILE_MODE_READ) { SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY; } else { SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE; } Return = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle); if (RETURN_ERROR (Return)) { if (OpenMode & EFI_FILE_MODE_CREATE) { // // In the create if does not exist case, if the opening in update // mode failed, create it and open it in update mode. The update // mode allows for both read and write from and to the file. // Return = SemihostFileOpen ( AsciiFileName, SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE, &SemihostHandle ); if (RETURN_ERROR (Return)) { Status = EFI_DEVICE_ERROR; goto Error; } } else { Status = EFI_NOT_FOUND; goto Error; } } // Allocate a control block and fill it FileFcb = AllocateFCB (); if (FileFcb == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error; } FileFcb->FileName = AsciiFileName; FileFcb->SemihostHandle = SemihostHandle; FileFcb->Position = 0; FileFcb->IsRoot = 0; FileFcb->OpenMode = OpenMode; Return = SemihostFileLength (SemihostHandle, &Length); if (RETURN_ERROR (Return)) { Status = EFI_DEVICE_ERROR; FreeFCB (FileFcb); goto Error; } FileFcb->Info.FileSize = Length; FileFcb->Info.PhysicalSize = Length; FileFcb->Info.Attribute = (OpenMode & EFI_FILE_MODE_CREATE) ? Attributes : 0; InsertTailList (&gFileList, &FileFcb->Link); *NewHandle = &FileFcb->File; return EFI_SUCCESS; Error: FreePool (AsciiFileName); return Status; }